Why this matters
As a Backend Engineer, you’ll build systems that must know who is calling (authentication) and what they’re allowed to do (authorization). You’ll implement login flows, protect APIs, maintain sessions or tokens, and enforce permissions—safely and reliably.
- Build login, logout, and password reset endpoints
- Secure API endpoints with session cookies or bearer tokens
- Verify JWTs and validate scopes/roles
- Prevent common attacks like credential stuffing and CSRF
- Apply least privilege with role-based or attribute-based checks
Quick note: The quick test is available to everyone. If you’re logged in, your progress will be saved automatically.
Concept explained simply
- Authentication (authN): Proving identity. Are you Alice?
- Authorization (authZ): Checking permissions. Can Alice do X?
Authentication answers “who,” authorization answers “what can they do.” You usually authenticate once, then authorize every request.
Mental model
Imagine a club with a doorman and a rope.
- Doorman checks your ID → authentication
- Rope and staff decide where you can go → authorization
- Your stamped wristband or badge → session or token proving you were checked
Key concepts and terms
- Session-based auth: Server creates a session record and sets a secure, HTTP-only cookie with a session ID.
- Token-based auth: Server issues tokens (often JWTs) that clients send in Authorization headers.
- JWT (JSON Web Token): Signed token with claims. Format: header.payload.signature. Must be verified, not trusted blindly.
- OAuth2 / OIDC: Standardized delegation/identity protocols used for “Login with X” and API access with scopes.
- RBAC: Role-Based Access Control (admin, editor, viewer). ABAC: Attribute-based (department=finance, ownerId=123).
- CSRF: Cross-Site Request Forgery; prevent with same-site cookies, CSRF tokens, and double-submit techniques.
- Password storage: Always hash with a slow algorithm (bcrypt, scrypt, Argon2). Never store plain text.
- MFA: Multi-factor authentication adds something you have/are in addition to password.
Worked examples
Example 1: Session cookie login flow
- User posts email + password to /login
- Server verifies password hash, creates a session row with userId, expiry, and a random sessionId
- Server sets Set-Cookie with a secure, HTTP-only, same-site cookie containing the sessionId
- Subsequent requests include the cookie; server looks up session and authorizes
// Verify password and set session cookie (pseudocode)
user = db.findUserByEmail(email)
if (!user || !verifyHash(password, user.passwordHash)) return 401
sessionId = randomId()
db.insertSession({ id: sessionId, userId: user.id, expiresAt: now + 7d })
setCookie('sid', sessionId, { httpOnly: true, secure: true, sameSite: 'Lax', path: '/' })
return 204
CSRF protection tip
Use SameSite=Lax or Strict cookies, and protect state-changing endpoints with CSRF tokens or require Authorization headers instead of cookies.
Example 2: Bearer token with JWT
- /login returns a signed JWT with userId, roles, exp
- Client sends Authorization: Bearer <jwt>
- Server verifies signature and expiry before trusting claims
// JWT verify middleware (pseudocode)
function verifyJWT(req) {
const auth = req.headers['authorization'] || ''
const [scheme, token] = auth.split(' ')
if (scheme !== 'Bearer' || !token) return 401
claims = verifySignatureAndExpiry(token, PUBLIC_KEY)
if (!claims) return 401
req.user = { id: claims.sub, roles: claims.roles }
return 200
}
Security note on JWT
- Always verify signature and alg; reject alg=none
- Validate exp, nbf, aud, iss when applicable
- Keep tokens short-lived; refresh with a secure flow
Example 3: OAuth2 Authorization Code (with PKCE)
- App sends user to provider’s authorize page with code_challenge
- User logs in with provider
- App receives code, exchanges it (with code_verifier) for tokens
- App uses access token to call the provider’s APIs
PKCE binds the code to your client, reducing interception risk.
Example 4: RBAC check
function authorize(requiredRole, user) {
if (!user) return false
return user.roles.includes(requiredRole)
}
// Example usage
if (!authorize('admin', req.user)) return 403
ABAC twist
// Owner rule: allow if user owns resource
function canEdit(user, resource) {
return user.roles.includes('admin') || resource.ownerId === user.id
}
Hands-on exercises
Do the exercises below. Aim for correctness first, then security hardening. Mirror your work with the checklist.
- Exercise 1: Build a secure session login endpoint with cookie + CSRF strategy
- Exercise 2: Implement JWT verification middleware and role checks
Self-check checklist
- Passwords are hashed with a slow algorithm
- Session cookie has HttpOnly, Secure, SameSite set
- State-changing endpoints are protected against CSRF
- JWTs are verified for signature, alg, exp (and aud/iss if used)
- Authorization checks are explicit and centralized
- Rate limiting/brute-force protection is in place
Common mistakes and how to self-check
- Trusting JWT without verifying signature. Self-check: Try a token with modified payload; server must reject it.
- Missing SameSite/HttpOnly on session cookies. Self-check: Inspect Set-Cookie; flags must be present.
- Long-lived tokens without rotation. Self-check: Ensure access tokens are short-lived; use refresh tokens properly.
- Authorization after action. Self-check: All writes must check permissions before database changes.
- Storing plain text passwords. Self-check: Confirm only hashes are stored; test with a fake breach dump.
Practical projects
- Personal notes API: Session-based auth, CSRF protection, and owner-only access.
- Task manager API: JWT auth, roles (admin, manager, worker), and per-project permissions.
- OAuth login demo: Authorization Code with PKCE to fetch basic profile.
What good looks like
- Clear separation: auth middleware, authorization helpers
- Explicit security headers and cookie flags
- Short token lifetimes, refresh rotation, and revocation list
Who this is for
- Beginners learning backend basics
- Frontend devs adding secure APIs
- QA/DevOps who need to understand auth flows
Prerequisites
- Comfortable with one backend runtime (e.g., Node, Python, Go, Java)
- Basic HTTP knowledge (headers, status codes, cookies)
- Basic database CRUD
Learning path
- AuthN vs AuthZ fundamentals (this lesson)
- Sessions and cookies in detail
- JWT and token-based APIs
- OAuth2/OIDC essentials
- Role and attribute-based authorization patterns
- Hardening: CSRF, rate limiting, password policies, MFA
Next steps
- Finish the exercises and run the quick test
- Refactor: centralize authorization checks
- Add logging for auth events and monitor failed logins
Mini challenge
Your team exposes POST /payments. The web app uses cookies. Design a CSRF defense and an authorization rule. Describe cookie flags, token strategy, and the role/owner checks you’ll implement.