OAuth 接入
采用标准 Authorization Code 模式。下面以 Web 服务端接入为例。
端点地址以应用详情页为准
不同应用的授权地址、Token 地址、用户信息地址可能不同。下面的 AUTHORIZE_URL、TOKEN_URL、USERINFO_URL 请替换成应用详情页展示的实际地址。
1. 创建应用
在聚合登录控制台创建应用,拿到:
client_idclient_secret(仅服务端保存)- 配置 回调地址(
redirect_uri),必须与应用白名单完全一致
2. 发起授权
把用户跳转到授权地址:
text
{AUTHORIZE_URL}
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fyour-site.com%2Fauth%2Fcallback
&scope=openid%20profile
&state=RANDOM_STRING参数:
| 参数 | 必填 | 说明 |
|---|---|---|
response_type | 是 | 固定 code |
client_id | 是 | 应用 ID |
redirect_uri | 是 | 必须与白名单一致,需 URL 编码 |
scope | 否 | 需要的权限范围 |
state | 建议必填 | 随机串,回调时校验,防 CSRF |
state 要存进会话(cookie / session),回调时比对,不一致直接拒绝。
3. 处理回调
用户同意后,浏览器会跳到:
text
https://your-site.com/auth/callback?code=CODE&state=STATE服务端校验 state 后,用 code 换 token:
bash
curl -X POST "$TOKEN_URL" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=CODE" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET" \
-d "redirect_uri=https://your-site.com/auth/callback"返回示例:
json
{
"access_token": "eyJ...",
"token_type": "Bearer",
"expires_in": 7200,
"refresh_token": "def...",
"openid": "user_unique_id"
}code 只能用一次
code 有效期很短(通常几分钟),且只能兑换一次。不要在前端兑换,也不要把 client_secret 发到浏览器。
4. 读取用户信息
bash
curl "$USERINFO_URL" \
-H "Authorization: Bearer $ACCESS_TOKEN"返回字段以实际为准,常见包括:
json
{
"openid": "user_unique_id",
"nickname": "昵称",
"avatar": "https://...",
"unionid": "跨应用统一 ID"
}5. 建立本地会话
- 用
openid(或unionid)查本地用户表; - 不存在则创建;
- 写入你自己的 session / JWT;
- 跳回业务页面。
不要把 access_token 直接当成本地登录态长期使用,它有自己的有效期。
6. 刷新与退出
刷新:
bash
curl -X POST "$TOKEN_URL" \
-d "grant_type=refresh_token" \
-d "refresh_token=REFRESH_TOKEN" \
-d "client_id=YOUR_CLIENT_ID" \
-d "client_secret=YOUR_CLIENT_SECRET"退出:清理本地会话,并按应用详情页给出的登出地址跳转,实现单点退出。
安全清单
- [ ]
redirect_uri精确匹配,不做模糊通配 - [ ] 校验
state - [ ]
client_secret只在服务端 - [ ]
code只兑换一次,兑换后立即失效 - [ ] token 不在 URL、日志、前端存储中明文出现
- [ ] 生产环境强制 HTTPS
常见错误
| 现象 | 原因 |
|---|---|
redirect_uri_mismatch | 回调地址与控制台白名单不一致(协议、域名、路径、末尾斜杠都算) |
invalid_grant | code 过期、已使用,或 redirect_uri 与授权时不一致 |
invalid_client | client_id / client_secret 错误,或密钥已重置 |
state 校验失败 | 会话丢失、跨域 cookie 问题、或遭遇 CSRF |
| 拿到 token 但取不到用户信息 | scope 不足,或 token 已过期 |