OAuth2 Authorization Code Grant流程中授权请求无需client secret的原因探讨
Great question—this is a common point of confusion, but the design makes perfect sense once you look at the different goals and constraints of each step in the flow. Let’s break it down:
1. The authorization request runs in a public, untrusted environment
The authorization request is initiated from the user’s browser (or a mobile app’s web view), where the client can’t safely store a client secret. Think about single-page apps (SPAs) or native mobile apps: all their code is exposed to the user (or easily reverse-engineered). If we required the client secret here, it would have to be included in frontend code, where it’s trivial for an attacker to steal. That would defeat the purpose of having a secret in the first place!
The client_id, on the other hand, is meant to be public—it’s just a way to identify your app to the authorization server. The server uses it to look up your app’s details (like the redirect URI) and show the user a proper consent screen.
2. The authorization request’s focus is user consent, not client authentication
At this stage, the core goal is to get the user’s permission to grant access to your app. The authorization server doesn’t need to strongly verify the client’s identity here—it just needs to confirm the client_id is valid, and that the redirect URI matches what’s registered for that client. The real trust check happens later, when exchanging the authorization code for a token.
3. The token request needs the secret to prevent authorization code misuse
Authorization codes can be intercepted (e.g., via a man-in-the-middle attack or a compromised user device). If any attacker who stole a code could exchange it for a token, that’s a huge security risk.
The token request happens directly between your client’s backend server and the authorization server—this is a private, trusted channel where you can safely send the client secret. Requiring the secret here ensures that only the legitimate client (who knows the secret) can redeem the authorization code. Even if an attacker gets the code, they can’t use it without the secret.
A quick note on public clients
For clients that can’t store a secret at all (like SPAs or mobile apps), the OAuth2 spec later introduced PKCE (Proof Key for Code Exchange) as an additional layer of security. PKCE uses a one-time code challenge instead of a secret to verify the client during the token exchange, but it still doesn’t require a secret in the initial authorization request.
内容的提问来源于stack exchange,提问作者ken5scal

