CMD Guide
HomeSystem DesignAuthentication

OAuth 2.0 & OIDC — Traced: “Login with Google”

Watch it happen, with real values

You sign up for Spotify and click “Continue with Google.” Here is the exact sequence — note your Google password is never given to Spotify.

 STEP 1 — Spotify redirects your browser to Google’s authorization endpoint:
   https://accounts.google.com/o/oauth2/v2/auth
        ?client_id=spotify-1234.apps.googleusercontent.com
        &redirect_uri=https://spotify.com/callback
        &response_type=code
        &scope=openid email profile
        &state=xyz789
        &nonce=abc123
        &access_type=offline      (Google-specific: ask for a refresh_token too)

 STEP 2 — Google authenticates you (if not already) and shows a CONSENT screen:
   "Spotify wants access to: your email, basic profile."   →  you click [Allow]

 STEP 3 — Google redirects your browser back to Spotify with a one-time CODE:
   https://spotify.com/callback?code=4/0AeanS0a9x...&state=xyz789   (short-lived, single-use)

 STEP 4 — Spotify’s SERVER (back-channel, not your browser) exchanges the code:
   POST https://oauth2.googleapis.com/token
        code=4/0AeanS0a9x... &client_id=spotify-1234... &client_secret=GOCSPX-secret
        &redirect_uri=https://spotify.com/callback &grant_type=authorization_code
   ← Google responds:
     { "access_token": "ya29.a0Af...", "id_token": "eyJhbGciOi...", "refresh_token": "1//x...", "expires_in": 3599 }

 STEP 5 — Spotify calls the API with the token:
   GET https://openidconnect.googleapis.com/v1/userinfo
       Authorization: Bearer ya29.a0Af...
   ← { "sub": "110248495...", "email": "you@gmail.com", "name": "You" }
   Spotify creates your account / logs you in. Done.

Why this is safe: your password stayed with Google; Spotify got a code in the browser (useless alone) and exchanged it for a token server-to-server using its secret. The token is scoped (email/profile only) and expires in an hour. One provider-specific knob is worth naming: access_type=offline in step 1 is what makes Google return the refresh_token in step 4 — omit it and you get only the access and id tokens. (Google issues the refresh_token on the first consent; on later logins add prompt=consent to force a re-issue. Per Google’s “OAuth 2.0 for Web Server Applications” docs — provider-specific, not part of the OAuth spec itself.)

OAuth 2.0 authorization-code flow
OAuth 2.0 authorization-code flow

Why the redirect-and-exchange dance?

The browser receives a one-time authorization code because the client cannot keep a secret in user-accessible code. In the SPA/mobile case you add PKCE: the client creates a random code_verifier, hashes it into a code_challenge sent with the redirect, and sends the original verifier to the token endpoint; the authorization server verifies the challenge before issuing tokens. This stops an attacker who intercepts the code from redeeming it.

The state parameter prevents login CSRF by binding the outgoing redirect to the incoming callback. A nonce in the OIDC request binds the id_token to the original login attempt and stops replay.

Server-to-server exchange keeps the client_secret out of the browser and the user’s password out of the app.

Single sign-on via a central identity provider
Single sign-on via a central identity provider

The two roles, made concrete

So: OAuth answers “what can this app access?”; OIDC adds “who is this user?” “Log in with Google” is OIDC.

SSO, traced

Because you already have a live Google session from step 2, when you later click “Login with Google” on a different app, Google skips the password prompt (you’re already authenticated) and goes straight to the redirect-with-code. One login, many apps — that’s Single Sign-On.

Which OAuth flow when?

Token hygiene

Takeaways


Re-authored as a from-scratch walkthrough for this guide.

id_token validation checklist

The id_token is a signed JWT, but a signature alone is not enough. Verify these five claims before you trust it.

CheckHowWhat failure looks like
1. SignatureFetch the IdP’s JWKS, pick the key matching kid, verify the JWT signature with that public key; pin the expected algAttacker forges a token with alg: none or RS256→HS256 confusion
2. Issuer (iss)iss must exactly equal the IdP’s issuer URL, e.g. https://accounts.google.comToken from a look-alike identity provider is accepted
3. Audience (aud)aud must equal your registered client_idToken minted for another app is replayed against yours
4. Expiry (exp)Reject if exp is in the past, allowing a small clock-skew buffer (usually ≤ 60 s)Expired or never-valid token is honored
5. NonceIf you sent nonce=abc123 in the auth request, nonce in the id_token must match exactlyReplay of an id_token from a different login attempt succeeds
def verify_id_token(token, client_id, expected_iss, expected_nonce, jwks):
    header = json.loads(base64url_decode(token.split('.')[0]))
    key = jwks.get_key(header['kid'])
    claims = jwt.decode(token, key, algorithms=['RS256'], issuer=expected_iss, audience=client_id)
    if claims.get('nonce') != expected_nonce:
        raise SecurityError('nonce mismatch')
    return claims

Grant-type decision map

Pick the OAuth 2.0 grant by the client’s ability to keep a secret and whether a human is present.

Client typeRecommended grantWhy
SPA / mobile appAuthorization code + PKCENo client secret in user-accessible code; PKCE binds the code to the app instance
Server-side web appAuthorization codeClient secret stays on the server during token exchange
Daemon / service-to-serviceClient credentialsNo human user; machine identity authenticated with a secret or certificate
Smart TV / CLI deviceDevice authorization grantDevice has no browser; user authorizes on a phone/laptop
Any new systemAvoid implicit and resource-owner passwordBoth are deprecated in OAuth 2.0 Security Best Current Practice

🪜 Drill ladder: OAuth 2.0 & OIDC

These are the follow-ups an interviewer uses to separate a candidate who has traced the flow from one who understands the threat model.

  1. L1 — Why PKCE? The authorization code is delivered through the browser, so a malicious app or network observer could steal it. PKCE binds the code to the original app instance: the app proves possession of the code_verifier that produced the code_challenge. Without it, public clients are open to code-interception attacks.
  2. L2 — What is the difference between state and nonce? state binds the outgoing redirect to the incoming callback, stopping login CSRF (an attacker tricking you into logging into their account). nonce binds the id_token to the original authentication request, stopping replay of an id_token from a different login.
  3. L3 — Where should tokens live? Prefer HttpOnly; Secure; SameSite=Lax cookies for session continuity. Avoid localStorage for long-lived tokens because an XSS payload can exfiltrate them in one line. For SPAs that need the access token in JavaScript, keep it short-lived (minutes) and pair it with a refresh token stored in a hardened cookie.
  4. L4 — Why not put the client secret in a SPA? A SPA’s source is fully visible. An attacker who extracts the secret can exchange stolen authorization codes for tokens themselves. That is why public clients use PKCE and no client secret.
🤖 Don't fully get this? Learn it with Claude

Stuck on OAuth 2.0 & OIDC — Traced: “Login with Google”? Open Claude, copy a block below, and it'll teach you this exact concept — visually and interactively.

🎨 Explain it visually

Build the mental picture, not memorization.

I just read a lesson on **OAuth 2.0 & OIDC — Traced: “Login with Google”** (System Design) and want to truly understand it. Explain OAuth 2.0 & OIDC — Traced: “Login with Google” from first principles using ONE vivid real-world analogy and a visual mental model — draw it as ASCII art or a clear step-by-step diagram — with a concrete example using real numbers. Then ask me one question to check I got the mental picture, and wait for my reply. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🤔 Walk me through it (interactive)

Socratic — adapts to where you're stuck.

Teach me **OAuth 2.0 & OIDC — Traced: “Login with Google”** interactively. Ask me ONE guiding question at a time, wait for my answer, and adapt to my confusion — build the idea with me step by step instead of explaining it all at once. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧪 Quiz me & fix my gaps

Active recall exposes what you missed.

Quiz me on **OAuth 2.0 & OIDC — Traced: “Login with Google”** with 5 questions, easy to tricky, ONE at a time. Tell me if each answer is right; at the end, explain clearly what I got wrong and why. If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.
🧠 Make it stick

Intuition + hook + flashcards for long-term memory.

Help me remember **OAuth 2.0 & OIDC — Traced: “Login with Google”** for the long term: give the one-sentence intuition, a memorable hook/mnemonic, a tiny worked example, and 3 active-recall flashcards (Q -> A). If you're unsure or a claim isn't standard, say so and reason from first principles instead of guessing.

📝 My notes