Exercise 1 — The flow
1-2. In your traffic: /authorize with response_type=code, code_challenge (S256), a random state; redirect with ?code=...&state=...; redemption (POST with code_verifier). Everything from the lesson, but yours.
- Altered
state→ allauth error (denied): it prevents flow CSRF (the callback of a login started by ANOTHER user being injected into you).
Exercise 2 — The id_token
- Standard OIDC claims:
iss(https://accounts.google.com),aud(your client_id),sub(stable user id),email,email_verified,exp,iat,nonce(if you asked for it),name/picture. - The JWT header carries
kid; Google's JWKS has several rotated public keys; you select bykidand verify RS256. Caching JWKS (with a refresh on unknown kid) is mandatory: don't query JWKS on every login. - Minimum checks: correct
iss(prevents tokens from another tenant/provider),aud= your client_id (prevents reuse of tokens issued to another app), unexpiredexp/iat(prevents replay of old tokens),nonceif you sent one (prevents replay of an injected code/token), andemail_verifiedfor linking (prevents account takeover).
Exercise 3 — Linking
- A (both verified): link — same human, one account. You add the social account to the local user; you don't create a duplicate (duplicating breaks their purchase history).
- B: NEVER link without
email_verified. Create a separate account or reject with a verification message. The attack without this rule: register at a lax provider with the victim's email → you take over their account in your system. - C: two local accounts (distinct identities until ownership is proven). Unification: an authenticated manual flow ("these accounts are yours" with proof via both providers) or support — automating the merge of purchases is an integrity problem (payments in whose name) you don't improvise.
Exercise 4 — Scopes
has_permissionreadsrequest.auth.scope(if you issued your tokens with scope) or maps the client (registered application → granted scopes):events:readfor listings,tickets:writeto reserve,refunds:writeonly for backoffice/trusted integrators.- 403 with
{"type": ".../missing-scope", "title": "Missing the tickets:write scope", "status": 403}: the integrator knows what to ask for without support.
Exercise 5 — ADR-0009 (skeleton)
Context: password registration causes abandonment and manual email verification. Decision: OIDC (Google) with allauth, linking by verified email, local account always. Rejected alternatives: password only (friction), magic links (they depend on email anyway, less standard). Consequences: cached JWKS, mandatory nonce/state, a local account decouples the provider's uptime after the first login; the password remains as an alternative method + MFA (20).
Professor's summary
- Authorization Code + PKCE is the only flow you will implement in 2026; the roles and state/nonce are part of the design, not the form.
- id_token = identity (validate it and create your user); access_token = calling the provider's APIs. Your API consumes YOUR identity issued after validating.
- Linking only with a verified email; otherwise you manufacture account takeover.
- Social login is the door; your system issues and governs the session. The provider can go down afterwards.
Next: Lesson 20 — Password hashing and MFA.