OAuth 2.0 & OpenID Connect
OAuth 2.0 is an authorization framework for delegated access — letting an app act on a user's behalf without ever handling their password. OpenID Connect (OIDC) is a thin identity layer on top that adds authentication: proving who logged in.
Every time you click "Continue with Google" or "Sign in with GitHub," you're using OAuth, and almost always OIDC. The hard part isn't the concept — it's picking the right flow and validating the tokens correctly.
TL;DR
- Authorization Code + PKCE — browser SPAs and mobile apps.
- Authorization Code — confidential server-side web apps (can hold a secret).
- Client Credentials — machine-to-machine, no user involved.
- Avoid Implicit flow — legacy, replaced by PKCE.
- For login identity, you want OIDC (ID Token + UserInfo), not raw OAuth.
Quick Example
The Authorization Code + PKCE flow, condensed — the client proves it owns the code it's redeeming:
Core Concepts
Roles
- Resource Owner — the user.
- Client — your application.
- Authorization Server — the identity provider (IdP).
- Resource Server — the API holding protected data.
Artifacts
- Authorization code — short-lived, exchanged for tokens.
- Access token — presented to the API.
- Refresh token — long-lived, used to get new access tokens.
- Scope — the permissions a client requests.
OIDC adds the ID Token (a JWT asserting who logged in) and the UserInfo endpoint for profile claims.
The Flows You Actually Use
Authorization Code (server-side web app)
Best when your app has a backend that can keep a client secret. The browser receives a code; the server exchanges it for tokens out of band.
Authorization Code + PKCE (SPA / mobile)
Same shape, plus a proof key (code_verifier / code_challenge) so an intercepted code is useless. This is the default for any "public" client that can't keep a secret.
Client Credentials (service-to-service)
No user involved. A service uses its own credentials to obtain an access token to call another service.
Choosing a Flow
Token Validation
ID tokens (OIDC)
- Verify the signature.
- Validate
iss,aud,exp, andnonce(when used). - Validated by the client — it proves the login event.
Access tokens
- Verify the signature (if it's a JWT).
- Enforce the expected
audfor your API and the required scopes. - Validated by the resource server (the API).
See JWT for the mechanics of validating signed tokens.
Scopes and Permissions
Use scopes to express capabilities, and keep them granular:
- Good:
read:profile,write:profile,read:projects - Avoid: a single "god" scope, or encoding resource IDs into scopes unless you truly need it.
Common Patterns
"Login with X" for a web app
Use OIDC for identity, then create your own app session/cookie after login. It's easier to revoke, rotate, and reason about your security boundary than passing IdP tokens around.
API + SPA
- SPA uses Authorization Code + PKCE.
- API accepts access tokens (JWT or opaque).
- Refresh token lives in an
HttpOnlycookie where possible.
Common Mistakes
Using the Implicit flow
Implicit was a workaround for old browsers; modern public clients use Authorization Code + PKCE.
Skipping token validation
Accepting an access token without checking aud, exp, and scopes lets tokens minted for another service slip through. Validate on every request.
Mishandling refresh tokens
Storing refresh tokens in localStorage, never rotating them, or not supporting revocation turns one stolen token into permanent access. Prefer HttpOnly cookies with rotation.
FAQ
What's the difference between OAuth and OpenID Connect?
OAuth 2.0 handles authorization (delegated access to resources). OIDC adds authentication on top, returning an ID Token that proves who the user is. If you want login, you want OIDC.
Which flow should a single-page app use?
Authorization Code with PKCE. The Implicit flow is deprecated, and SPAs can't safely hold a client secret, so PKCE protects the authorization code instead.
Is an access token the same as an ID token?
No. The access token is for calling APIs (the resource server validates it). The ID token is for the client to learn who logged in. Don't send ID tokens to your APIs as credentials.
Do I still need CSRF protection with OAuth?
Yes, for the flow itself — use the state parameter to prevent CSRF on the redirect, and nonce to bind the ID token to your request. See CSRF.
Related Topics
- JWT — Validating the tokens OAuth issues
- API Security — Enforcing scopes at the API
- Authentication — Where OAuth fits among auth strategies
- Password Security — Securing first-party login
- Security Headers — Hardening the browser side