Free — no signup required

OIDC in Action: Tokens and Flows

2 min read

The Artifacts of OIDC

When an OIDC flow completes successfully, the application receives tokens. These tokens are passed in API headers using the Bearer scheme: Authorization: Bearer <token>.

1. ID Token (AuthN artifact)

This is the "passport." It contains claims — structured assertions — about the user: their name, email address, unique user ID (sub), and which identity provider issued it. The ID Token is almost always a JWT (JSON Web Token): a Base64-encoded, cryptographically signed document with three parts separated by dots.

header.payload.signature

You can decode the payload (the middle section) to read the claims in plain JSON. The signature ensures the token hasn't been tampered with. The ID Token is meant for the application to know who is logged in — it should not be sent to external APIs.

2. Access Token (AuthZ artifact)

This is the "hotel key card." The application presents this token when calling APIs or accessing resources. It grants permission to perform specific actions (defined by scopes). Access tokens are short-lived by design — typically 15 minutes to 1 hour — to limit the damage if one is stolen.

3. Refresh Token

A long-lived token used to obtain new access tokens without requiring the user to log in again. Refresh tokens must be stored securely (never in browser localStorage) because they are high-value targets.

The Authorization Code Flow

How do we get these tokens safely? The standard method for web and mobile apps is the Authorization Code Flow.

The naive approach — sending tokens directly to the browser — is dangerous because browser environments are exposed to JavaScript injection attacks. Instead:

  1. The user clicks "Log in with Google" in your app.
  2. Your app redirects the user's browser to Google's Authorization Server with a request that includes your app's client_id, requested scope, and a redirect_uri.
  3. The user authenticates with Google (enters their password, passes MFA).
  4. Google redirects the browser back to your redirect_uri with a short-lived, one-time-use authorization code in the URL query string.
  5. Your application's backend server (not the browser) takes that code and makes a direct, server-to-server POST request to Google's token endpoint, including the code and your app's client_secret.
  6. Google validates everything and returns the ID Token, Access Token, and Refresh Token directly to your backend.

The critical security property: sensitive tokens are exchanged in a back-channel (server-to-server), never exposed in the browser's URL bar or history. The authorization code is useless without the client_secret, which only your backend knows.

This is one of 18 chapters

Every chapter is free — Kubernetes, Terraform, SRE, distributed systems, and more — with fast daily review built in.

Sign up free