How It Works: AuthN/AuthZ — Sessions, JWT, 2FA, OAuth2, CSRF
Updated: 2025-08-24
Summary
Authentication proves identity; authorization determines permissions. For browsers, default to server sessions + secure cookies and CSRF defenses. For APIs/mobile, use short‑lived JWT access tokens with refresh tokens. Layer 2FA, strong secrets management, and defense‑in‑depth on every hop.
Sessions (Browser)
- Server stores session state (Redis). Client holds opaque cookie.
- Set cookie flags: HttpOnly; Secure; SameSite=Lax (or Strict for sensitive flows).
- Rotate session on login and privilege changes; short TTL + sliding refresh.
- CSRF protection: double‑submit token or SameSite plus custom header.
# Example Set-Cookie (HTTP response)
Set-Cookie: sid=abc123; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=7200
# CSRF: double submit (store token in session, send in header)
X-CSRF-Token: <random-128-bit>
# Server checks header value matches token in session
JWT (APIs / Mobile)
- Self‑contained claims signed with strong alg (RS256/EdDSA).
- Short access token TTL (5–15 min) + refresh token (days) bound to device.
- Validate: signature, issuer, audience, expiry, not‑before.
- Rotate signing keys; publish JWKs; support kid for key lookup.
- Revoke on risk events via allow/deny lists or rotating `jti` with server list.
// Go: verify RS256 JWT (using github.com/golang-jwt/jwt/v5)
func Verify(tokenStr string, jwkSet *jose.JSONWebKeySet) (*jwt.Token, error) {
keyfunc := func(t *jwt.Token) (any, error) {
kid, _ := t.Header["kid"].(string)
for _, k := range jwkSet.Keys {
if k.KeyID == kid { return k.Key, nil }
}
return nil, errors.New("unknown kid")
}
return jwt.Parse(tokenStr, keyfunc, jwt.WithAudience("api"), jwt.WithIssuer("https://auth.example.com"))
}
OAuth2/OIDC (Login with Google/Apple/etc.)
- Use Authorization Code + PKCE for public clients.
- Store minimal profile; map provider subject → internal user ID.
- Keep redirect URIs strict; validate state to prevent CSRF.
- Refresh/rotate tokens on schedule; handle provider outages gracefully.
2FA & Trusted Devices
- Deliver OTP via app/email; rate‑limit attempts.
- “Remember device” = signed, HttpOnly cookie + device record server‑side.
- Expire trust on password change, device removal, or risk signals.
- Backup codes printed once; store hashed.
RBAC and Secure API Design
- Enforce authorization at the edge and in each service.
- Prefer role + fine‑grained permissions/attributes (ABAC) for sensitive ops.
- Deny by default; minimal scopes; never trust client‑supplied roles.
Security Headers & HTTPS
Strict-Transport-Security: max-age=31536000; includeSubDomains
Content-Security-Policy: default-src 'self'
Referrer-Policy: no-referrer
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Secrets Management
- Store secrets in vault/KMS; mount via short‑lived tokens.
- Rotate keys regularly; audit usage; avoid secrets in images or logs.
- Pin dependencies; verify signatures; lock down CI/CD secrets.
Auditability
- Log auth flows with request_id and user_id (no passwords/tokens).
- Record 2FA events, scope grants, and admin changes.
- Retain logs per policy; encrypt at rest and in transit.
Pitfalls
- Long‑lived JWTs with broad scopes.
- Missing CSRF protections on cookie‑based APIs.
- Overloading refresh tokens (use rotation and reuse‑detection).
- Not checking `aud`/`iss` → token confusion.
Taylor Swift
“I keep my side of the street clean.”
Comments
Post a Comment