1. OAuth2.0 授权码流程全解析:授权码、令牌端点、重定向 URI、scope 参数、PKCE 扩展
1.1 什么是授权码流程
授权码流程(Authorization Code Flow)是 OAuth2.0 最完整、最安全的授权模式,广泛应用于支付 SDK、开放平台 API 等场景。核心思想是:客户端不直接接触用户凭据,而是通过一个临时凭证(授权码)向授权服务器换取访问令牌(Access )。即使授权码在传输过程中泄露,攻击者也必须在极短时间内同时拥有 client_secret 或 PKCE 验证码 才能兑换令牌,安全性远高于隐式流程。
适用场景:支付回调、银行对账、电商订单同步、任何需要长期访问资源的服务端应用。客户端必须有能力保护 client_secret(即机密客户端),或搭配 PKCE 扩展(公开客户端也可安全使用)。
1.2 核心参与者与角色
| 角色 | 英文名称 | 职责 | 典型实例 |
|---|---|---|---|
| 资源所有者 | Resource Owner | 拥有受保护资源,决定是否授权 | 支付平台商户 / 个人用户 |
| 客户端 | Client | 代表资源所有者请求授权,获取令牌后访问资源 | 电商后端 / 支付 SDK |
| 授权服务器 | Authorization Server | 认证资源所有者,发放授权码与访问令牌 | 支付宝 OAuth 服务 / 微信开放平台 |
| 资源服务器 | Resource Server | 持有受保护资源,验证令牌后返回数据 | 支付订单 API / 用户信息 API |
角色边界:授权服务器与资源服务器在物理上可以是同一台服务器,但逻辑上必须分离。生产环境中建议拆分,以便独立扩缩容与安全隔离。
1.3 授权码流程六步交互
下图展示了从用户触发授权到客户端获取受保护资源的完整交互路径:
1.4 授权端点与令牌端点
授权服务器对外暴露两个核心端点,职责严格分离:
| 端点 | URL 模式 | 方法 | 用途 | 返回结果 |
|---|---|---|---|---|
| 授权端点 | /oauth/authorize | GET | 用户认证并授权,返回授权码 | 重定向 URI + ?code=xxx |
| 令牌端点 | /oauth/ | POST | 客户端用授权码换取令牌 | JSON 含 access_、_type、expires_in |
# 授权端点请求示例(客户端构造的重定向 URL)
GET https://auth.payplatform.com/oauth/authorize
?response_type=code
&client_id=app_5f3a2b9e
&redirect_uri=https://api.merchant.com/callback
&scope=payment:read+payment:write
&state=xyz789abc
# 令牌端点请求示例(客户端向授权服务器 POST)
POST https://auth.payplatform.com/oauth/
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code
&code=AuR3kF9sWq
&redirect_uri=https://api.merchant.com/callback
&client_id=app_5f3a2b9e
&client_secret=sk_9e8d7c6b5a
# 令牌端点成功响应
HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
{
"access_": "at_v2_8f7e6d5c4b3a2",
"_type": "Bearer",
"expires_in": 7200,
"refresh_": "rt_x1y2z3w4v5u6",
"scope": "payment:read payment:write"
}
⚠ 生产警告:令牌端点必须使用 HTTPS + 双向 TLS 或至少证书固定;
client_secret 绝不可暴露在浏览器或移动端安装包中。若无法保证机密性,必须启用 PKCE。
1.5 重定向 URI(Redirect URI)
重定向 URI 是授权流程的安全锚点。授权服务器只向预先注册的 URI 发送授权码,防止攻击者伪造回调地址截获凭证。
- 注册机制:客户端注册时必须提交完整的 redirect_uri,支持 HTTPS 协议。localhost 仅允许开发调试。
- 精确匹配:授权服务器对比请求中的 redirect_uri 与注册列表,禁止使用通配符或子路径模糊匹配。
- 防开放重定向:禁止将用户输入直接拼接到 redirect_uri 参数中,避免攻击者利用客户端作为跳板。
# 注册重定向 URI 示例(客户端管理后台配置)
- 注册 URI: https://api.merchant.com/callback
- 允许的变体:
https://api.merchant.com/callback?source=pos
- 拒绝的变体:
http://api.merchant.com/callback (协议不匹配)
https://evil.com/callback (域名未注册)
https://api.merchant.com/callback/../admin (路径遍历)
1.6 Scope 参数详解
scope 定义了客户端请求的权限范围,授权服务器在用户授权页面展示该范围,用户可部分勾选或拒绝。支付场景常见 scope:
| scope 值 | 含义 | 对应 API 权限 |
|---|---|---|
payment:read | 读取支付订单 | 查询订单状态、账单明细 |
payment:write | 创建/修改支付 | 发起付款、退款、撤销 |
user:info | 读取用户基本信息 | 获取昵称、头像、手机号 |
offline_access | 离线刷新令牌 | 获取 refresh_ 以长期维持访问 |
# scope 参数格式(空格分隔,URL 编码)
# 原始 scope: payment:read payment:write offline_access
# URL 编码后:
scope=payment%3Aread+payment%3Awrite+offline_access