这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
OAuth 授权码流程
为什么叫「授权码」
Web 应用最常用的是授权码流程(Authorization Code)。它的核心设计是:浏览器只负责「拿一个短期、一次性的 code」,真正的令牌交换发生在服务端——这样 access token 永远不会暴露给浏览器,也绕开了浏览器存储令牌的安全难题。
完整流程
OAuth 授权码流程
点击「使用 GitHub 登录」
用户决定用第三方身份登录你的系统重定向到第三方授权页
携带 client_id、scope、redirect_uri、state用户确认授权范围
第三方展示「允许应用获取哪些信息」第三方带 code 跳回你的系统
code 短期有效、一次性使用校验 state 与 redirect_uri
防止 CSRF 与开放重定向用 code 换取 access token
在服务端调用,不暴露给浏览器获取用户信息并绑定本地账号
创建 / 关联本地用户,建立本地会话安全要点:
state 防 CSRF、redirect_uri 白名单校验、code 一次性短期有效、换 token 必须在服务端完成。
几个容易被忽略的细节
state:防 CSRF
state 是一个随机值,发起时带上,回调时校验是否一致。攻击者可以伪造一个「授权完成」的回调,但拿不到 state,就无法冒充流程完成。
redirect_uri:白名单
回跳地址必须严格匹配你预先注册的白名单。否则攻击者构造一个「授权成功 → 跳到钓鱼站」的链接(开放重定向),就能诱导用户授权后踩进陷阱。
code:短期、一次性
授权码是「换令牌的凭证」,必须短期有效、一次性使用。拿到 code 只换一次 token,换完作废。泄露的 code 即使被截获,也很快过期、无法重放。
换 token 必须在服务端
用 code 换 access token 的请求,要带着你的 client_secret,只能在服务端发,绝不能在前端代码里做(否则 secret 泄露,任何人都能冒充你的应用)。
为什么要分两步
有人会问:为什么不直接在回调里带 access token?
两步(code → token)的价值在于:
- access token 只出现在服务端到服务端的通道里,浏览器全程接触不到。
- 服务端可以在换 token 时校验
client_secret,确认「确实是我的应用在请求」。
这就是授权码流程比「隐式流程」更安全的原因——隐式流程把 token 直接给浏览器,通常不推荐用于敏感场景。
完成授权之后
拿到 access token 后:
- 调用第三方的用户信息接口获取身份。
- 在本地绑定或创建账号(下一节展开)。
- 建立你自己的本地会话,用户就算「登录成功」了。
下一节看第三方账号怎么和本地账号绑定,以及 scope 最小权限。
发现内容有问题?
告诉我们哪里需要改进。
