OAuth and OIDC Deep Dive

OAuth 2.0 is "delegated authorization": let app A act on behalf of user U at service S, without giving A the user's password. OIDC layers identity on top: tell app A who user U is. Together they're how nearly every "Sign in with…" button works in 2026, and how nearly every API-to-API call between cloud services works.

OAuth has a reputation for being confusing because the spec accumulated flows over a decade and the names ("implicit," "password," "code") describe ten subtly different things. OAuth 2.1 (RFC drafted 2024) cleans up the deprecations. Use it.

OAuth vs OIDC

If you're building "Sign in with Google" you need OIDC. If you're letting a third-party app post on behalf of a user, you need OAuth. Most SSO use cases are OIDC. Most "API access between services" cases are OAuth.

The same authorization server (Auth0, Okta, Keycloak, Cognito, Azure AD) handles both.

The flow you should pick

In 2026, Authorization Code with PKCE is the right answer for nearly every OAuth flow.

1. Client redirects user to authorization server with:
     - client_id
     - redirect_uri
     - response_type=code
     - scope=...
     - state=<random>
     - code_challenge=<SHA256 of random verifier>
     - code_challenge_method=S256

2. User authenticates with auth server (and consents to scopes).

3. Auth server redirects back to redirect_uri with ?code=AUTH_CODE&state=...

4. Client backend posts to /token with:
     - grant_type=authorization_code
     - code=AUTH_CODE
     - redirect_uri=...
     - client_id, client_secret  (if confidential client)
     - code_verifier=<original random>

5. Auth server validates (especially that SHA256(verifier) == challenge), returns:
     - access_token (used to call APIs)
     - refresh_token (used to get new access tokens)
     - id_token (OIDC; identity claim)

PKCE (Proof Key for Code Exchange) was introduced for mobile apps (where the client secret can't be kept secret) and has been promoted to a universal requirement in OAuth 2.1. Use it always, even for confidential clients with secrets.

If a tutorial tells you to use these, the tutorial is out of date. Use authorization code + PKCE.

Confidential vs public clients

Both use authorization code + PKCE. The only difference is whether the token endpoint call carries client_secret.

Tokens and what they are

Common confusion: people use the ID token as an access token. Don't. The ID token tells you who; the access token authorizes what.

JWT access tokens and validation

Many auth servers issue access tokens as JWTs. The receiving API validates:

  1. Signature against the issuer's public key (fetched from /.well-known/jwks.json, cached).
  2. iss matches the expected issuer.
  3. aud includes your API's identifier.
  4. exp is in the future.
  5. scope or scp includes the required permission.

Use a library. Hand-rolled JWT validation is one of the most common security bugs in the wild. The classic flaws:

Refresh tokens

Refresh tokens are powerful. A leaked refresh token gives an attacker continued access until you detect and revoke it.

Defences:

Scope design

Scopes describe what an access token can do. Bad scope design:

Better:

Apps request the minimum scopes they need. Users see the consent screen; ask for the minimum.

OIDC specifics

ID tokens are JWTs with a defined claim set:

The userinfo endpoint returns the same claims (and possibly more) and is queryable with the access token. Useful for fresh data that might have changed since the ID token was issued.

Common mistakes

Operational concerns

When OAuth/OIDC isn't the answer

Further reading