Guide - Web Authentication

Sources:

Overview

Understanding the difference between authentication and authorization:

  • Authentication: Verifying Identity (401 Unauthorized)
  • Authorization: Verifying Permissions (403 Forbidden)

Two main approaches to username/password authentication:

  • Stateful (Session-based using Cookies)
  • Stateless (Token-based using JWT/OAuth)

Session-Based Authentication

Flow

  1. User submits login credentials (email & password)
  2. Server verifies credentials against database
  3. Server creates temporary user session
  4. Server issues a cookie with a session ID
  5. User sends cookie with every request
  6. Server validates cookie using session store & grants access
  7. When user logs out, server deletes session and clears cookie

Sequence Diagram

sequenceDiagram
    participant User
    participant Browser
    participant Server
    participant Database

    User->>Browser: Enters email & password
    Browser->>Server: Submits login credentials
    Server->>Database: Verify credentials
    Database-->>Server: Credentials valid?
    alt Credentials valid
        Server->>Server: Create temporary session
        Server->>Browser: Issue cookie with session ID
        Browser-->>User: Authentication successful
        loop User requests
            Browser->>Server: Request with cookie
            Server->>Server: Validate session ID
            Server-->>Browser: Response with data
        end
        User->>Browser: Logs out
        Browser->>Server: Logout request
        Server->>Server: Delete session
        Server->>Browser: Clear cookie
    else Credentials invalid
        Server-->>Browser: 401 Unauthorized
        Browser-->>User: Login failed
    end

Session Features

FeatureDescription
Session StoreRedis, Memcached, or database for session data
Session IDCryptographically random, stored in cookie
Cookie FlagsHttpOnly, Secure, SameSite for security
ExpirationServer-controlled session lifetime

Pros & Cons

ProsCons
Server can revoke sessions instantlyRequires session storage (memory/database)
Session data stays on server (secure)Horizontal scaling requires shared session store
Simple to implementCSRF protection required
Works with all clientsCookies don’t work well for mobile/APIs

Token-Based Authentication (JWT)

Flow

  1. User submits login credentials
  2. Server verifies credentials
  3. Server generates and signs a JWT
  4. Server sends JWT to client
  5. Client stores JWT (localStorage, sessionStorage, or cookie)
  6. Client sends JWT with every request (Authorization header)
  7. Server validates JWT signature & grants access
  8. No server-side session storage needed

JWT Structure

header.payload.signature

Header:

{
  "alg": "HS256",
  "typ": "JWT"
}

Payload:

{
  "sub": "user_id",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622
}

Signature:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

Pros & Cons

ProsCons
Stateless - no server storageCannot revoke tokens before expiration
Scales horizontally easilyPayload visible (base64 encoded, not encrypted)
Works well for APIs and mobileToken size larger than session ID
Cross-domain friendlyRefresh token strategy required for long sessions

OAuth 2.0

Grant Types

Grant TypeUse Case
Authorization CodeWeb apps with backend (most secure)
Authorization Code + PKCESPAs and mobile apps
Client CredentialsMachine-to-machine
ImplicitLegacy, not recommended
Resource Owner PasswordLegacy, not recommended

Authorization Code Flow

sequenceDiagram
    participant User
    participant App
    participant AuthServer
    participant ResourceServer

    User->>App: Clicks "Login with Provider"
    App->>AuthServer: Redirect to /authorize
    AuthServer->>User: Show login/consent screen
    User->>AuthServer: Approves
    AuthServer->>App: Redirect with authorization code
    App->>AuthServer: Exchange code for tokens
    AuthServer->>App: Access token + refresh token
    App->>ResourceServer: API request with access token
    ResourceServer->>App: Protected resource

Security Best Practices

Set-Cookie: session_id=abc123; 
  HttpOnly; 
  Secure; 
  SameSite=Strict; 
  Path=/; 
  Max-Age=3600
FlagPurpose
HttpOnlyPrevents JavaScript access (XSS protection)
SecureOnly sent over HTTPS
SameSite=StrictCSRF protection
Path=/Cookie scope

Token Security

  • Store in httpOnly cookie (not localStorage) when possible
  • Use short expiration times (15 min for access tokens)
  • Implement refresh token rotation
  • Validate all claims (iss, aud, exp)

Password Hashing

# Use bcrypt, Argon2, or scrypt - NEVER MD5 or SHA1
import bcrypt
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(12))

When to Use What

ScenarioRecommendation
Traditional web appSession + Cookie
SPA with same-origin APISession + Cookie (via proxy)
SPA with cross-origin APIJWT in httpOnly cookie
Mobile appJWT with secure storage
Public APIOAuth 2.0 / API Keys
MicroservicesJWT for service-to-service

See Also


(c) No Clocks, LLC | 2024