Google account + a project in Google Cloud Console (free OAuth credentials). Don't look at solutions.md before submitting.
Exercise 1 — The flow, observed
- Configure django-allauth with the Google provider (client_id/secret in per-environment settings — 27). Start it and do the full login from your app.
- During the flow, capture (DevTools → Network): the
/authorizeURL (arecode_challengeandstatethere?), the redirect with?code=, and the redemption call. List the lesson's 6 steps seen in your own traffic. - Change the
statein the callback by hand and repeat: what error? Which attack does that validation prevent?
Exercise 2 — The id_token under the magnifying glass
- Paste the
id_tokeninto jwt.io: list the claims (iss,aud,sub,email,email_verified,exp,iat,nonce). - Verify the signature against Google's public JWKS (
https://www.googleapis.com/oauth2/v3/certs): which key matches bykid? - List the 4 minimum checks your backend would make besides the signature, and which attack each one prevents.
Exercise 3 — Account linking (the classic pitfall)
- Scenario A: a user registered with email+password (verified email). Then they sign in with Google with THE SAME verified email. What should happen? Implement the linking.
- Scenario B: an unverified Google email (a provider that doesn't verify) with the same email: what does your code do? Implement the rule: never link without
email_verified=true. - Scenario C: same human, two providers (Google + GitHub with different emails): two accounts? A manual unification mechanism? Decide and record it in the ADR.
Exercise 4 — Your API with scopes (a preview of 21)
- If TicketFlow exposed an API to integrators: define 3 scopes (
events:read,tickets:write,refunds:write) and the check in your viewsets (has_permissionby scope). - Write the 403 response with the missing scope (RFC 7807 format,
type: missing-scope).
Exercise 5 — ADR-0009: "Sign in with Google (OIDC)"
Context (registration friction, free email verification), decision (allauth + OIDC + linking by verified email), alternatives (password+MFA only, magic links), consequences (provider dependency only at login, JWKS caching, local account always).
Exercise 6 — Scopes and the flow map
- Implement TicketFlow's 5 scopes (§6) in your fake IdP and add the per-endpoint scope-verification middleware: the checkout demands
tickets:purchase, the organizer panelorganizer:*. Test: a token without the scope → 403 with problem+json (26) saying WHICH scope was missing. - Human consent: write the consent screen (or JSON) the user sees: each scope translated into human language (51: the two-way translation). How do you explain "tickets:purchase" to your aunt?
- The flow-meter: classify 4 real integrations of your project in the §5 table (the worker→gateway, the buyer's login, the physical box-office terminal, the old SPA you inherited). Which one demands a migration and why?
Submit
Paste claims, checks and linking decisions. Next: Lesson 20 — Password hashing and MFA.