You've clicked "Sign In with Google" a thousand times. You've probably built login flows that use it. But if someone asked you to explain exactly what happens between the click and the redirect — could you?
Most developers treat OAuth like a black box. Copy the library, paste the config, pray. I want to crack it open.
The Problem OAuth Solves
Before OAuth, sharing access meant sharing passwords. Literally. If a photo-printing service needed your Flickr photos, you'd hand over your Flickr credentials. The printing service could read your messages, delete your account, do whatever it wanted. There was no concept of scoped access.
OAuth fixes this with a simple idea: let the user grant limited access without revealing their credentials. The app gets a token that says "I can read photos" — not a skeleton key to the whole account.
The Authorization Code Flow (Step by Step)
This is the flow you hit every time you click a social login button. Here's what actually happens:
1. Your app redirects the user to the authorization server.
The redirect URL contains your app's client ID, the permissions you're requesting (scopes), and a redirect URI. It also includes a state parameter — a random string your app generates to prevent CSRF attacks.
2. The user authenticates and consents.
Google (or whoever) shows the user a login screen and a consent page: "This app wants to read your email and profile. Allow?" The authorization server handles all of this. Your app never touches the user's password.
3. The server redirects back with an authorization code.
After consent, the browser redirects to your redirect URI with a short-lived authorization code in the query string. This code is useless on its own — it's a one-time ticket.
4. Your server exchanges the code for tokens.
Your backend sends the authorization code, plus your client secret, directly to the authorization server. This is server-to-server — no browser involved. You get back an access token (for API calls) and often a refresh token (for getting new access tokens later).
5. You use the access token to call APIs.
Attach the token to API requests as a Bearer header. The resource server validates it and returns data.
Why It's a Two-Step Dance
The code-then-token exchange isn't just bureaucracy. The authorization code travels through the browser (front-channel) — it's exposed in URLs, browser history, referrer headers. If that code was the access token, anyone snooping the URL gets full API access.
By requiring a server-side exchange with the client secret, OAuth ensures that even if someone intercepts the code, they can't use it without your server credentials. The access token only ever travels through the secure back-channel.
PKCE: Because Mobile Apps Don't Have Secrets
Mobile and single-page apps can't store client secrets safely — the code runs on the user's device. PKCE (Proof Key for Code Exchange) patches this gap.
Your app generates a random code_verifier, hashes it into a code_challenge, and sends the challenge with the initial authorization request. When exchanging the code for tokens, you send the original verifier. The server hashes it and compares. An attacker who intercepts the code doesn't have the verifier, so the exchange fails.
PKCE is now recommended for all OAuth clients, not just public ones. The current best practice (RFC 9126) pushes PKCE everywhere.
Common Mistakes I Still See
-
Not validating the
stateparameter. This is CSRF protection. Skip it and attackers can trick users into linking their account to the attacker's. - Storing tokens in localStorage. Accessible to any XSS attack. Use httpOnly cookies or secure server-side storage.
- Requesting too many scopes. Ask for what you need. Users (rightfully) bail when an app asks for their contacts, calendar, and email for a to-do list.
- Ignoring token expiration. Access tokens expire for a reason. Use refresh tokens properly instead of asking users to re-authenticate.
The Valet Key Analogy
Think of OAuth like a valet key for your car. A valet key lets someone drive the car but not open the trunk or glove box. You don't hand the valet your house keys, car title, and Social Security number. You give them exactly enough access to do one job.
That's OAuth. Scoped, temporary, revocable access. No passwords shared.
OAuth clicked for me when I stopped reading specs and started tracing actual HTTP requests. If you're still fuzzy, open your browser dev tools and watch the redirects next time you click "Sign In with Google." Seeing the code, state, and redirect in action makes the whole thing tangible.
Top comments (0)