We're going to make a fairly basic user account system. There are two concepts involved:
- User accounts: a username and password combination
- User roles: a name for a collection of permissions, things users can do
Let's see what we'll make. You can try it.
Here's what the home page looks like to someone who isn't logged in:
This is what an anonymous user will see. An anonymous user is someone using a browser to access the app, but who hasn't logged in.
- See a products list
Here's the products list:
This is what it would look like on a small screen, like a phone. The menu has changed to a dropdown version.
An authenticated user is someone who is logged in. What they see depends on their role. We'll have two roles:
- Administrator: someone administering the app, an IT person.
- Manager: a business manager in marketing, production, whatevs.
Let's check what they see on the home page.
Here's what someone with the admin role will see:
There are three differences from the home page for anon users:
- The Login link has changed to Logout
- The top menu has a new entry, to see a list of users
- There's a users link in the body of the page
The users list is what you would expect:
The second is labelled "Roles" rather than "Role." Does that mean someone can have more than one role?
Aye. Good point. Maybe Sarah goes on vacation for a week, and Linda takes over her job. You'd add the admin role to Linda's account. She would see all the extra stuff for both roles.
If you want, you can log in, the password for the Sarah's account is SarahTheMagnificent.
Here's what the home page looks like for someone with the manager role:
There are three differences from anon's home page:
- Login has changed to Logout
- There's a sales link in the top menu
- There's a sales link in the body of the page
Here's what the sales list looks like:
Linda's password is LindaTheAwesome.
Here's what users with different roles see:
- Anon: products
- Admin: products, and users
- Manager: products, and sales
URL guessing attack
Hey, those reports, like the user list, they have URLs, right?
Indeed. For example, the user report is at http://webappexamples.skilling.us/user-accounts/products/users.php.
What's to stop an anon user from typing the URL into a browser?
Ooo, good question! That's called URL guessing, and is a common attack.
Here's what Georgina is talking about. The home page for admins is:
The home page for anons doesn't have links to the user list.
The links to the user list have gone, but the page itself is still there. Someone could type the URL into their browser...
... and see the report, right?
We have to code for that, so this happens when anon tries to see the users report:
Hiding menu items isn't enough. You have to restrict pages as well.
Here's the login form:
Here's what Sarah would see when she's filled in the form:
The password is hidden.
To logout, users click the logout link in the menu.
That takes them to the anon home page you saw before:
If the app can't find a user with the given name and password, it should show an error:
Hang on. The error message doesn't say whether the error is in the user name, the password, or both. Wouldn't you want to do that, so people know what to fix?
Hmm. What do you thing, y'all?
No, I'd leave it as is. Maybe someone is trying to login by guessing user names and passwords. If you tell them where the error is, you're helping them.
Like, say they make a guess, and get two messages, that the user name is wrong, and the password is wrong. Then they try another guess, and get one error, that the password is wrong. Now they know a valid user name.
Right. This is the one case where we don't want to give specific error messages.
- User accounts have roles, that control menu items, and what pages they access.
- An anonymous user is someone using a browser to access a page in the app, but who hasn't logged in.
- An authenticated user is someone who is logged in. What they see depends on their role.
- An account can have more than one role.
- A URL guessing attack is when someone types restricted URLs directly into a browser.
- Use general error messages on login forms.