The Engineering of OAuth 2.0: Delegation Without Impersonation
Before OAuth existed, if a third-party app (like Yelp) wanted to find your friends on Google Contacts, it literally asked you to type your raw Google password into the Yelp website. This was a catastrophic security anti-pattern. OAuth 2.0 was engineered to solve one specific problem: Delegated Authorization. It allows you to give a valet the "valet key" to drive your car, without giving them the master key to open the trunk or steal the car entirely.
Part 1: The Front-Channel vs. Back-Channel Paradigm
The genius of the Authorization Code Flow lies in its strict separation of communication channels.
The Front-Channel is the user's web browser. It is incredibly insecure. Malware, browser extensions, or XSS attacks can easily intercept URLs and read data passing through the browser. Therefore, OAuth never sends the highly-sensitive Access Token through the browser.
Instead, the Authorization Server (Google) redirects the browser back to the App with a temporary, useless-on-its-own mathematical string called an Authorization Code.
This Code is immediately captured by the App's backend server. The App's server then opens
a highly secure, TLS-encrypted connection directly to Google's server—this is the Back-Channel. The App proves its identity using a tightly guarded Client Secret, hands
over the Code, and Google responds with the actual Access Token. The browser never sees
the Token, making it mathematically impossible for XSS malware to steal it during the
login dance.
Part 2: Why Mobile Apps Require PKCE
The standard Authorization Code flow requires a Client Secret. But if you
compile a Native iOS/Android app or a React SPA, you mathematically cannot hide a secret.
Anyone who downloads the app can decompile the binary and extract the secret.
To solve this, OAuth 2.1 mandates PKCE (Proof Key for Code Exchange) for public clients. Instead of a static hardcoded secret, the app generates a dynamic secret on the fly for every individual login attempt.
- The App generates a massive random string: the
code_verifier. - It hashes this string (SHA-256) to create a
code_challenge. - It sends the challenge to the Auth Server via the Front-Channel URL. The Auth server remembers: "This specific login attempt is locked to this hash."
- When the App tries to swap the Auth Code for the Token on the Back-Channel, it sends the
original, unhashed
code_verifier.
The Auth Server hashes the verifier. If it perfectly matches the challenge sent in step 3, it proves the app requesting the Token is the exact same app that initiated the login, effectively replacing the static Client Secret with cryptographic proof-of-work.
Part 3: Access Tokens vs. Refresh Tokens
Access Tokens act as bearer cash. Whoever holds the token can spend it at the API. Because they cannot be easily revoked (especially JSON Web Tokens), Security best practices dictate they must expire aggressively—usually within 15 to 60 minutes.
To prevent the user from having to log in every 15 minutes, the Auth Server issues a Refresh Token alongside the original Access Token.
The Refresh Token is useless for fetching API data, but it acts like a golden ticket to
the Auth Server. When the Access Token expires and the API returns a 401 Unauthorized, the App's backend quietly sends the Refresh Token to the Auth Server on the
Back-Channel to mint a brand new Access Token, entirely invisibly to the user.
Part 4: OAuth is NOT Authentication (Enter OIDC)
A critical, often misunderstood fact: OAuth 2.0 is purely an Authorization protocol. It does absolutely nothing to verify who the user actually is. It only issues tokens that say "The holder of this token is allowed to read photos."
To actually parse the user's Identity (Name, Email, Profile Picture), the industry layered
a protocol on top of OAuth 2.0 called OpenID Connect (OIDC).
When an app requests the openid scope in step 1, the Auth Server responds
with the standard Access Token, plus an ID Token (a signed JWT) containing the
verifiable identity profile of the authenticated user.