Build the mental model
Authentication answers 'who are you?' - password, passkey, OAuth, magic link, and tokens are all ways of proving identity.
Authorization answers 'what can you do?' - being logged in doesn't grant every action. Real apps check authorization per action.
Login Form
The user submits credentials through a form.
HTTPS Request
Credentials travel to the backend over an encrypted HTTPS connection.
Backend Verifies
The backend checks credentials against stored (hashed) data.
Session/Token Created
On success, the backend creates a session or issues a token representing the authenticated user.
Authenticated Requests
Future requests carry that session or token, and the backend checks it each time.
Passwords should never be stored as plain text - hashing (one-way) and salting (adding random data) are the standard approach.
Never write your own crypto
Instead of writing your own password hashing or cryptographic code, use established, audited libraries or managed authentication services.
- Authentication
- The process of verifying who a user is, such as through a password, passkey, OAuth login, or valid session/token.
- Authorization
- The process of determining what an authenticated user is allowed to do.
LOGIN FLOW
----------
LOGIN FLOW
-----------
Login Form -> HTTPS Request -> Backend Verifies Credentials
-> Session/Token Created -> Authenticated Requests
AUTHENTICATION VS AUTHORIZATION
---------------------------------
Authentication: "Who are you?"
-> checked once per login (session/token proves identity)
Authorization: "What can you do?"
-> checked on every sensitive action (role/permission check)Connect it to a real scenario
The function first checks whether an authenticated session exists at all, then only checks action-specific authorization if that passes.
- Question 1: who is this? (authentication)
- Question 2: what are they allowed to do right now? (authorization)
Never write your own password hashing or crypto
Always use established, audited libraries or managed authentication services - custom cryptographic implementations create serious, hard-to-see vulnerabilities.
Try the working example
function checkAccess(user, action) {
const authenticated = Boolean(user && user.sessionValid);
if (!authenticated) {
return { authenticated: false, authorized: false, result: "denied: not logged in" };
}
const permissions = {
user: ["view own account", "edit own account"],
admin: ["view own account", "edit own account", "manage all users", "delete any account"],
};
const authorized = (permissions[user.role] || []).includes(action);
return {
authenticated: true,
authorized,
result: authorized ? "allowed" : "denied: not authorized for this action",
};
}
const regularUser = { sessionValid: true, role: "user" };
console.log("Regular user deletes another account:", checkAccess(regularUser, "delete any account"));
console.log("Regular user edits own account:", checkAccess(regularUser, "edit own account"));Logs the regular user's delete attempt as authenticated: true, authorized: false, and their own-account edit as authenticated: true, authorized: true.5-minute try-it
Add an admin user object to the code and confirm that only the admin's checkAccess call for 'delete any account' returns authorized: true.
One important caution
Assuming being logged in (authenticated) automatically means being allowed to perform any action (authorized) - authorization must be checked per action.
Writing a custom password hashing scheme instead of relying on audited libraries or managed authentication providers.
Authentication or Authorization?
MDN Web Docs - HTTP authentication — How the Web Works