Authentication & Authorization
01 / 04

OAuth 2.0 & OpenID Connect

Authentication: OAuth 2.0 & OpenID Connect

OAuth 2.0 is an authorization framework — it lets users grant third-party apps access to their resources without sharing credentials. OpenID Connect (OIDC) is a thin identity layer on top of OAuth 2.0 that adds authentication.

OAuth 2.0 Roles

  • Resource Owner — the user who owns the data

  • Client — the application requesting access (your app)

  • Authorization Server — issues tokens (Google, GitHub, Auth0, your own)

  • Resource Server — the API being accessed (Google APIs, GitHub API)

Grant Types (Flows)

Authorization Code + PKCE  — for user-facing web/mobile apps (RECOMMENDED)
  1. App redirects user to Authorization Server with code_challenge (PKCE)
  2. User authenticates and grants consent
  3. AS redirects back with authorization_code
  4. App exchanges code + code_verifier for access_token + refresh_token
  5. App uses access_token to call Resource Server APIs

  PKCE (Proof Key for Code Exchange): prevents auth code interception attacks.
  Required for public clients (SPAs, mobile apps). Use for all new flows.

Client Credentials — for machine-to-machine (no user involved)
  1. Service POSTs client_id + client_secret to AS
  2. AS returns access_token (no refresh token)
  3. Service uses access_token to call other services

Device Flow — for CLIs, smart TVs (no browser)
  1. App requests device_code and shows user_code to user
  2. User visits URL and enters user_code on another device
  3. App polls for token until user approves

Implicit flow: DEPRECATED — use Authorization Code + PKCE instead
Resource Owner Password: DEPRECATED — share credentials directly (legacy only)

Authorization Code + PKCE Flow

// 1. Generate PKCE code verifier and challenge
const codeVerifier = base64urlEncode(crypto.randomBytes(32))
const codeChallenge = base64urlEncode(sha256(codeVerifier))

// 2. Redirect to Authorization Server
const authUrl = new URL('https://auth.example.com/oauth/authorize')
authUrl.searchParams.set('response_type', 'code')
authUrl.searchParams.set('client_id', 'my-client-id')
authUrl.searchParams.set('redirect_uri', 'https://app.example.com/callback')
authUrl.searchParams.set('scope', 'openid email profile')
authUrl.searchParams.set('state', randomState)          // CSRF protection
authUrl.searchParams.set('code_challenge', codeChallenge)
authUrl.searchParams.set('code_challenge_method', 'S256')
window.location.href = authUrl.toString()

// 3. Handle callback (app receives code)
const code = new URLSearchParams(window.location.search).get('code')
// verify state matches

// 4. Exchange code for tokens
const response = await fetch('https://auth.example.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code,
    redirect_uri: 'https://app.example.com/callback',
    client_id: 'my-client-id',
    code_verifier: codeVerifier,
  }),
})

OpenID Connect (OIDC)

OIDC adds authentication on top of OAuth 2.0:
  - ID Token (JWT) — contains user identity claims (sub, email, name, picture)
  - UserInfo endpoint — GET /userinfo with access_token to get user profile
  - Discovery document — /.well-known/openid-configuration (auto-discovery)

OIDC Scopes:
  openid    — required for OIDC; returns ID token with sub claim
  email     — adds email + email_verified claims
  profile   — adds name, picture, given_name, family_name, locale
  address   — postal address
  phone     — phone number

ID Token validation (must do on client/server):
  1. Verify signature using AS public keys (from JWKS endpoint)
  2. Verify iss = expected issuer
  3. Verify aud = your client_id
  4. Verify exp > now (not expired)
  5. Verify iat is reasonable (not too old)
  6. Verify nonce if included in auth request

Popular OIDC providers:
  Auth0, Okta, AWS Cognito, Keycloak (self-hosted), Google, GitHub (partial OIDC)

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free