设备码流(CLI / 桌面端)
RFC 8628 设备授权:设备端拿 device_code 轮询,用户在 auth 域确认页输入 user_code 并在 RankHub App 内批准。
适合输入受限的设备(CLI、桌面端、电视盒子):设备上不打开浏览器,而是显示一段短代码, 让用户在手机或另一台电脑上完成确认。
确认发生在 https://auth.rankhub.cc/oauth/device 这个页面上:用户输入代码后,
RankHub 会像普通 OAuth 授权一样,把"哪台设备、哪个应用、要什么权限"交给 RankHub App
由用户点确认。设备端只负责轮询令牌。
第一步:申请设备码
curl -sS -X POST https://auth.rankhub.cc/v1/oauth/device_authorization \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'client_id=your-client-id' \
-d 'scope=openid profile'{
"device_code": "dc_…",
"user_code": "ABCD-EFGH",
"verification_uri": "https://auth.rankhub.cc/oauth/device",
"verification_uri_complete": "https://auth.rankhub.cc/oauth/device?user_code=ABCD-EFGH",
"expires_in": 600,
"interval": 5
}| 字段 | 说明 |
|---|---|
device_code | 设备侧轮询凭据,不要给用户看 |
user_code | 8 位(XXXX-XXXX,字母表去掉了易混的 I / O);输入时忽略大小写与分隔符 |
verification_uri | 确认页地址;直接展示给用户,或把它做成二维码 |
verification_uri_complete | 带 user_code 预填的版本,用户扫码/点开即可跳过输入 |
expires_in | 默认 600 秒 |
interval | 5 秒。比这更快会拿到 slow_down |
应用必须已过审且启用,否则这里就返回 401 invalid_client。
第二步:用户在确认页完成确认
把 verification_uri(或 verification_uri_complete)展示给用户即可,不需要你实现任何确认 UI:
- 用户打开
https://auth.rankhub.cc/oauth/device,输入user_code(或直接点开带参数的链接); - 页面展示应用名、Logo 与权限,并提供「打开 RankHub App」与二维码;
- 用户在 RankHub App 里确认(或拒绝);
- 页面轮询到结果后显示「设备已授权」——此时设备端下一次轮询就会拿到令牌。
为什么要绕到 App 确认
RankHub 的授权确认一直发生在 App 内(平台没有网页登录页)。设备确认页复用了同一条确认链路, 所以用户看到的应用与权限信息、以及"谁能批准"的判定,与普通 OAuth 授权完全一致。
第三步:轮询令牌
curl -sS -X POST https://auth.rankhub.cc/v1/oauth/token \
-d 'grant_type=urn:ietf:params:oauth:grant-type:device_code' \
-d 'device_code=dc_…' \
-d 'client_id=your-client-id'RFC 8628 的状态码在这里不是一律 400:
| 情况 | HTTP | body |
|---|---|---|
| 用户还没批准 | 200 | { "error": "authorization_pending", … } |
| 轮询太快 | 200 | { "error": "slow_down", … } |
| 用户拒绝 | 400 | { "error": "access_denied", … } |
| 设备码过期 | 400 | { "error": "expired_token", … } |
| 成功 | 200 | 正常令牌响应(同授权码流程) |
authorization_pending 与 slow_down 是 HTTP 200,很多 HTTP 客户端会把 2xx 当成功。
请显式检查 body 里有没有 error,并按 interval 退避。
成功后的令牌响应与授权码流程一致(access_token / refresh_token / 可选 id_token),
后续调用与刷新见令牌、刷新与撤销。
确认页内部做了什么(排障用)
如果用户反馈"输入代码后一直等待",按这个顺序看:
| 现象 | 原因 |
|---|---|
| 确认页提示代码无效 | user_code 抄错,或设备码已超过 expires_in |
| 确认页说"这个代码已被其他账号确认" | 同一 device_code 已经绑定到别的 RankHub 账号 |
设备侧一直 authorization_pending | 用户还没在 App 里点确认(或 App 没打开成功) |
设备侧 access_denied | 用户在 App 里拒绝了 |
设备侧 expired_token | 超过 expires_in 仍未完成确认,需要重新申请设备码 |
设备码与 user_code 是两行独立的 artifact:确认页只认真实的 device_code 关联,
所以同一个应用并发多个待批准请求也不会串。