Basic Docs
authsecurity

Authentication & JWT

How auth works, tokens, and OAuth 2.0 flows explained.

Auth Flow Overview

Modern authentication is stateless: the server issues a signed token and never stores session state. Every subsequent request carries the token, and the server verifies it cryptographically — no database lookup required.

Login
Server validates
Token issued
Client stores
Send with requests

Session vs Token

Sessions store state on the server; tokens encode state in the client. Each approach has clear trade-offs depending on your scale and architecture.

Session-basedToken-based (JWT)
State stored on serverState encoded in token
Easy to revoke (delete session)Hard to revoke before expiry
Requires sticky sessions or shared storeStateless — scales horizontally
Cookie with session ID sent automaticallyToken sent manually in Authorization header
Best for monoliths and server-rendered appsBest for APIs, SPAs, and microservices

JWT Anatomy

A JWT is three Base64URL-encoded JSON objects joined by dots. The signature ties the header and payload together — if any bit changes, the signature check fails and the token is rejected.

JWT Structure
// JWT = three Base64URL parts joined by dots
// eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyMTIzIn0.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

// Header — signing algorithm and token type
{ "alg": "HS256", "typ": "JWT" }

// Payload — claims: user data and expiry
{ "sub": "user123", "role": "admin", "exp": 1700000000 }

// Signature — proves the token was not tampered with
HMACSHA256(base64url(header) + "." + base64url(payload), secret)
Three Parts of a JWT
Header — algorithm (HS256/RS256) and token type
Payload — claims: sub, iat, exp, role, and custom fields
Signature — HMAC or RSA proof that header + payload are untouched

OAuth 2.0 Flow

OAuth 2.0 lets users grant your app limited access to a third-party service without sharing passwords. The authorization code flow is the standard for web apps.

Authorization Code Flow
1
User
2
App
3
Auth Server
4
Consent
5
Code
6
Token
7
API
1
Redirect to Provider
App redirects the user to the OAuth provider (Google, GitHub) with client_id, redirect_uri, and requested scopes.
2
User Grants Consent
The provider shows a consent screen listing the permissions your app is requesting. The user approves or denies.
3
Receive Authorization Code
On approval, the provider redirects back to your redirect_uri with a short-lived authorization code in the query string.
4
Exchange Code for Token
Your server POSTs the code plus your client_secret to the provider's token endpoint. This exchange happens server-side, keeping the secret safe.
5
Use Access Token
The provider returns an access token (and optionally a refresh token). Use it to call the provider's API to fetch user profile data.

Security Best Practices

Token Lifecycle
Issue
Token signed and returned to client
Active
Token accepted by protected APIs
Near Expiry
15–60 min window closing
Refresh
Client silently exchanges refresh token
New Token
Fresh access token issued, old rotated out
Expire
Stale token rejected — re-authenticate if needed
!Store Tokens in httpOnly Cookies
Never store JWTs in localStorage — JavaScript can read it, making it vulnerable to XSS. Use httpOnly, Secure, SameSite=Strict cookies so the token is invisible to scripts and sent only over HTTPS.
!Keep Access Tokens Short-Lived
Access tokens should expire in 15–60 minutes. Long-lived tokens are a liability — if leaked, an attacker has extended access with no way to revoke them without a blocklist.
Use Refresh Tokens
Issue a long-lived refresh token (stored in httpOnly cookie) to silently obtain new access tokens. Rotate refresh tokens on every use and invalidate old ones to detect token theft.
Built: 4/8/2026, 12:01:11 PM