CodeOath
← All posts
Auth & Security60 min total · 19 parts

OAuth 2.0 and JWT Explained: How "Login with Google" Actually Works

Contents — Part 4 of 19: The Authorization Code Flow, Step by Step
Part 4 of 19 · ~1 min

The Authorization Code Flow, Step by Step

This is the flow behind essentially every "Login with X" button on the web, and the one worth memorizing exactly.

OAuth 2.0 authorization code flow diagram

  1. User clicks "Login with Google" on your site.
  2. Your app redirects the browser to Google's authorization endpoint, with your client_id, a redirect_uri, the scope (what you're asking permission for — e.g. "read their email"), and a state parameter (covered in the CSRF section below).
  3. Google shows a login/consent screen. The user authenticates directly with Google — your app never sees, touches, or has the opportunity to log their Google password.
  4. Google redirects back to your redirect_uri with a short-lived, single-use authorization code in the URL query string, plus the same state value you sent.
  5. Your backend exchanges that code — along with your app's secret client_secret — for an access token (and, for OpenID Connect, an ID token) by calling Google directly, server-to-server, at a token endpoint.
  6. Your backend uses the access token to call Google's API on the user's behalf, and typically creates its own session (a cookie) so the user stays logged in to your app going forward, independent of Google.
Browser                     Your App (Client)                 Google (Auth Server)
   |                              |                                    |
   |--- clicks "Login" ---------->|                                    |
   |                              |--- redirect to Google ------------>|
   |<---------------------------- redirect w/ client_id, scope, state -|
   |--- follows redirect, logs in & consents at Google ---------------->|
   |<--- redirect back to redirect_uri with `code` + `state` ----------|
   |--- browser forwards code -->|                                    |
   |                              |--- POST code + client_secret ----->|  (server-to-server)
   |                              |<--- access_token, id_token --------|
   |                              |--- calls Google API w/ token ----->|
   |<--- sets session cookie -----|                                    |