Skip to content

πŸ” Authentication - Sessions, JWT, & OAuth2

Authentication proves who a user is; Authorization proves what they can do. A Programmer designs authentication systems to be β€œleast privilege” by default and ensures that even if a token is stolen, the β€œblast radius” is minimized.


The traditional approach where the server stores user state in memory or a database (like Redis).

  • How it works: Upon login, the server creates a session and returns a Session ID in a Set-Cookie header. The browser sends this cookie with every subsequent request.
  • Pros:
    • Instant Revocation: You can kill a session immediately by deleting it from the server.
    • Security: Cookies with HttpOnly and SameSite flags are highly resistant to XSS and CSRF.
  • Cons:
    • Scalability: Requires a shared session store (Redis) if you have multiple server instances.

A compact, URL-safe means of representing claims to be transferred between two parties.

  • How it works: The server signs a JSON object containing user data and sends it to the client. The client sends it back in the Authorization: Bearer <token> header. The server verifies the signature without needing to query a database.
  • Pros:
    • Stateless: Excellent for microservices and horizontal scaling.
    • Decoupled: Different services can verify the token as long as they have the public key (asymmetric) or secret (symmetric).
  • Cons:
    • Revocation is Hard: Once issued, a JWT is valid until it expires.
    • Size: JWTs can become large if you store too many β€œclaims,” adding overhead to every request.

OAuth2 is not an authentication protocol; it is an authorization framework that allows a third-party app to access resources on behalf of a user. OpenID Connect (OIDC) is an identity layer on top of OAuth2.

  • Resource Owner: The user.
  • Client: The application requesting access.
  • Authorization Server: The server issuing tokens (e.g., Auth0, Keycloak, Google).
  • Resource Server: The API that holds the user’s data.
  • Authorization Code Flow (with PKCE): The gold standard for Web and Mobile apps.
  • Client Credentials: Used for machine-to-machine (M2M) communication (Service A talking to Service B).

FeatureSessionsJWTOAuth2 / OIDC
StorageServer-side (Redis/DB)Client-side (Local/Cookie)Usually Centralized Provider
RevocationImmediateDifficult (requires Blacklist)Managed by Provider
MicroservicesHard (requires shared state)Easy (stateless)Best (standardized)
ComplexityLowModerateHigh

Never issue a long-lived Access Token.

  • Access Token: Short-lived (5–15 mins). Used for API calls.
  • Refresh Token: Long-lived (days/weeks). Used to get a new Access Token.
  • Programmer’s Move: Implement Refresh Token Rotation. Every time a refresh token is used, issue a new one and invalidate the old one. If an old one is reused, it’s a sign of a breachβ€”revoke all tokens for that user.
  • Local Validation: Service checks the signature of the JWT. Fast, but might miss if the user was recently banned.
  • Introspection: Service asks the Auth Provider if the token is still valid. Slower, but provides real-time security.

Don’t share the same β€œsecret” across all microservices.

  • Strategy: The Identity Service signs tokens with a Private Key. All other services verify them using a Public Key. If a single service is compromised, the attacker cannot forge new tokens.

πŸ’‘ Note: Stop building custom β€œUser/Password” tables for every project. Using a specialized Identity Provider (IdP) like Keycloak, Auth0, or Firebase Auth handles complex flows like MFA, Password Reset, and Social Login more securely than you can likely build from scratch.