OAuth 2.0 流程
授权授予与令牌。
OAuth 2.0 流程 是 CoddyKit 上的免费 Cyber Security Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Cyber Security Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Cyber Security Academy 课程共包含 4 节课。
OAuth 2.0 实际解决的问题
OAuth 2.0 是一种委托授权框架。它允许用户向第三方应用授予对另一项服务上资源的有限访问权限,而无需共享密码。
- 它关注的是授权(应用可以执行哪些操作),而不是身份验证(用户是谁)。
- 应用会收到一个具有范围限制的
access_token,而不会收到用户凭据。
防御人员必须牢记:OAuth 本身无法证明身份。将访问令牌当作登录证明,是 OIDC 所要解决的典型错误。
四种角色
每个 OAuth 流程都涉及四种角色。正确厘清这些角色对于威胁建模至关重要。
- 资源所有者 — 拥有数据的用户。
- 客户端 — 请求访问权限的应用。
- 授权服务器(AS) — 在用户同意后签发令牌。
- 资源服务器(RS) — 保存受保护数据并验证令牌的应用程序接口。
这些角色之间存在信任边界。客户端遭到入侵,或 AS 的权限过于宽松,都会破坏整个信任链。
Roles:
Resource Owner -> grants consent
Client -> requests + uses tokens
Authorization Server -> issues tokens
Resource Server -> validates tokens授权码授权模式
授权码授权模式是网页和移动应用推荐使用的流程。它将面向用户的重定向与机密的令牌交换分开。
- 用户会被重定向到 AS,以进行身份验证并表示同意。
- AS 会将短期有效的
code返回到已注册的重定向 URI。 - 客户端通过后端通道在服务器端用授权码交换令牌。
由于令牌通过后端通道获取,因此不会出现在浏览器地址栏或历史记录中。
GET /authorize?response_type=code
&client_id=app123
&redirect_uri=https://app.example/cb
&scope=read:profile
&state=xyz
// then back-channel:
POST /token grant_type=authorization_code&code=...PKCE:代码交换证明密钥
PKCE(RFC 7636)强化了授权码授权模式,现在建议所有客户端使用,包括机密客户端。
- 客户端生成随机的
code_verifier,并将其哈希值作为code_challenge发送。 - 交换令牌时,客户端必须提供原始验证器。
这会将授权码绑定到最初的请求方,从而阻止截获授权码的攻击者兑换令牌。
code_verifier = random 43-128 chars
code_challenge = BASE64URL(SHA256(verifier))
/authorize ... &code_challenge=...&code_challenge_method=S256
/token ... &code_verifier=<original>客户端凭据授权模式
客户端凭据授权模式适用于机器到机器的访问,此时不涉及用户(例如后端服务调用应用程序接口)。
- 客户端使用自身凭据进行身份验证,并接收访问令牌。
- 通常不存在用户同意,也不存在刷新令牌。
请严格限制这些令牌的范围,并轮换客户端密钥。切勿使用此流程冒充最终用户。
POST /token
grant_type=client_credentials
client_id=service-a
client_secret=***
scope=orders:read访问令牌与刷新令牌
OAuth 会签发两种主要的令牌类型,其生命周期和处理规则大不相同。
- 访问令牌 — 生命周期短,每次调用时都发送给资源服务器。请将其视为持有者凭据。
- 刷新令牌 — 生命周期长,仅用于向 AS 请求新的访问令牌。
刷新令牌价值很高。请安全存储,将其绑定到客户端,并支持撤销。
POST /token
grant_type=refresh_token
refresh_token=<long-lived>
client_id=app123持有者令牌与传输
大多数 OAuth 访问令牌都是持有者令牌:任何持有令牌的人都可以使用它,就像使用现金一样。
- 始终通过 TLS 传输;切勿放在 URL 中,否则会泄露到日志和引荐来源中。
- 通过
Authorization标头发送。 - 对于高风险 API,请考虑使用发送方约束令牌(DPoP、mTLS)。
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
// AVOID:
GET /api/data?access_token=... // leaks in logs隐式授权已弃用
旧版隐式授权会直接将令牌返回到重定向 URI 片段中。现在,OAuth 2.0 安全 BCP 已不再建议使用它,并且 OAuth 2.1 已将其移除。
- 令牌会通过浏览器历史记录、引荐来源标头和日志泄露。
- 由于没有后端通道,客户端身份验证更弱。
对于 SPA,请改用 PKCE 授权码流程。
state 参数与 CSRF 防护
state 参数可以保护重定向步骤免受 CSRF 攻击。客户端生成一个随机值,将其存储在会话中,并在回调时进行验证。
- 如果返回的
state不匹配,请拒绝该响应。 - 这样可以防止攻击者将自己的授权码注入受害者的会话。
before: session.state = randomNonce()
/authorize ... &state=<nonce>
on callback:
if (req.state !== session.state) reject()作用域与最小权限
作用域表示令牌授予的访问权限粒度。请在每个步骤都应用最小权限原则。
- 只请求功能所需的作用域(
read:profile,而不是admin)。 - 资源服务器必须在每个端点上执行作用域检查,不能只信任有效令牌。
权限同意范围过大是现实中常见的风险:用户会批准那些请求远超实际所需权限的应用。
常见 OAuth 配置错误
大多数 OAuth 事故源于配置,而不是协议本身。
- 开放重定向/宽松的 redirect_uri 匹配会让攻击者窃取授权码。
- 缺少
state或 PKCE 会导致 CSRF 和授权码注入。 - 访问令牌长期有效且没有撤销机制。
- 将访问令牌当作身份验证断言。
请注册精确的重定向 URI,并严格验证它们。
redirect_uri allowlist:
EXACT: https://app.example/cb
NOT: https://app.example/* (too broad)快速检查:保护 SPA 身份验证
请选择下面场景应使用的正确现代流程。
回顾:OAuth 2.0 流程
要点:
- OAuth 2.0 是委托授权,而不是身份验证。
- 四种角色:资源所有者、客户端、授权服务器和资源服务器。
- 授权码 + PKCE 是 Web、移动应用和 SPA 的默认方案。
- 客户端凭据用于机器间访问。
- 使用
state、严格的重定向 URI 匹配、短期有效的访问令牌,并在各处使用 TLS 来进行保护。 - 隐式授权和密码授权已弃用。
常见问题解答
「OAuth 2.0 流程」课时是免费的吗?
是的 — 「OAuth 2.0 流程」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Cyber Security Academy 课程的其余内容,请升级到 CoddyKit PRO。 Cyber Security Academy 课程共包含 4 节课。
「OAuth 2.0 流程」这节课中我会学到什么?
授权授予与令牌。 你通过在浏览器中直接运行的动手代码来练习 Cyber Security Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Cyber Security Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Cyber Security Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「OAuth 2.0 流程」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Cyber Security Academy 课中编写并运行代码吗?
能。每节 Cyber Security Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- OAuth 2.0 流程
- OpenID Connect(OIDC)
- SAML 与联合身份
- 令牌攻击与强化