跳转到内容

设备码授权流程

查看 Markdown

设备码授权适合不能安全保存应用 client-auth 私钥的客户端:CLI、启动器、终端工具、共享设备,以及其他公共客户端。客户端向 Sudomimus 请求一组短暂有效的 deviceCode / userCode,把用户码展示给用户,引导用户到浏览器确认,然后轮询直到批准变成普通的 Sudomimus 应用令牌。

这条流程遵循 OAuth 2.0 Device Authorization Grant(RFC 8628) 的模型:发起客户端拿到 device code 和 user code,用户在有浏览器能力的 user agent 中批准,客户端持续轮询直到授权完成。Sudomimus 保留标准 device-flow 形状,但最终返回的是 Sudomimus 应用令牌。

它是独立于 Connect 和 Native direct-issue 的接入路径:

路径请求靠什么证明
Connect应用私钥签出的 client-auth JWT
Native direct-issueSteam ticket 或 AccessKey secret 这样的平台凭据
设备码授权公共客户端开启码会话,浏览器里的用户批准它

公开 HTTP 服务是 device-api.sudomimus.com。浏览器批准页面仍然由 via.sudomimus.com 承载。

步骤发起方端点结果
1. 开始客户端device-api POST /device-authorize{ deviceCode, userCode, verificationUri, verificationUriComplete, expiresIn, interval }
2. 批准浏览器中的用户via.sudomimus.com/device用户登录、确认显示的码,并批准或拒绝
3. 轮询客户端device-api POST /device-token等待状态、轮询指令、拒绝、过期,或 { accessToken, refreshToken }
4. 继续使用客户端connect-api POST /refresh后续令牌轮换使用普通 Connect 令牌操作

只有客户端能看到 deviceCode。只有用户看到并确认 userCode/device-token 成功后会消费这次设备会话,所以同一个 deviceCode 不能再签发第二组令牌。

客户端先提交应用 anchor:

Terminal window
curl -X POST https://device-api.sudomimus.com/device-authorize \
-H "Content-Type: application/json" \
-d '{
"applicationAnchor": "your-application"
}'

成功响应:

{
"applicationAnchor": "your-application",
"deviceCode": "dvc_...",
"userCode": "WDJB-MJHT",
"verificationUri": "https://via.sudomimus.com/device",
"verificationUriComplete": "https://via.sudomimus.com/device?user_code=WDJB-MJHT",
"expiresIn": 600,
"interval": 5
}

/device-authorize 接收 client-auth JWT。应用通过配置选择开放这条路径:它必须有一条启用的 Layer 3 DEVICE_CODE ReturnRule。如果缺少这条规则,请求会被拒绝。

在客户端界面清楚展示 userCode,并让用户打开浏览器批准页面:

访问 https://via.sudomimus.com/device
输入验证码:WDJB-MJHT

如果可以,优先打开 verificationUriComplete。它会预填用户码,也最适合做成二维码或终端里的可点击链接:

https://via.sudomimus.com/device?user_code=WDJB-MJHT

浏览器页面会再次展示应用和验证码,让用户确认自己批准的是同一个客户端会话。浏览器永远不会收到 deviceCode,也不会显示 access token 或 refresh token;它只负责批准或拒绝这次待处理会话。

客户端用私有的 deviceCode 轮询 /device-token

Terminal window
curl -X POST https://device-api.sudomimus.com/device-token \
-H "Content-Type: application/json" \
-d '{
"deviceCode": "dvc_..."
}'

轮询频率不要快于返回的 interval。用户还在操作时,/device-token 会返回 OAuth 风格的轮询错误:

{
"error": "authorization_pending"
}

批准完成后,同一个端点会返回普通 Sudomimus 应用令牌:

{
"applicationAnchor": "your-application",
"accessToken": "...",
"refreshToken": "...",
"claims": {
"email": { "requirement": "OPTIONAL", "state": "GRANTED" },
"firstName": { "requirement": "OFF", "state": "UNKNOWN" },
"lastName": { "requirement": "OFF", "state": "UNKNOWN" }
}
}

claims 块展示应用的 claim policy 与用户当前共享决定的合并结果。实际 token payload 仍遵循普通 Sudomimus token 规则。

设备码授权只负责最初这次公共客户端交换。一旦 /device-token 成功,refresh token 就属于普通 Sudomimus 应用会话模型。

后续使用 Connect API 令牌操作:

  • POST /refresh 轮换 refresh token 并签发新的 access token。
  • POST /logout 结束当前 refresh-token family。
  • POST /introspect 检查 token。
  • POST /revoke-all 做应用级会话吊销。

这些操作见管理会话;轮询状态机见设备码轮询与错误

应用必须允许浏览器侧认证和 realize 检查通过:

要求
Layer 1现有认证方式,例如邮箱验证码或通行密钥
Layer 2能允许该账户的现有身份规则
Layer 3一条 DEVICE_CODE ReturnRule

DEVICE_CODE 是 Layer 3 返回方式,不是新的认证方式。用户仍然通过应用已有的 Layer 1 方法登录,也仍然要通过 Layer 2 检查后,设备会话才能被批准。

当客户端是公共客户端、无法保密 client-auth 私钥时,选择设备码授权。典型场景包括发给用户安装的 CLI、桌面启动器、纯终端环境,或者需要用户在另一台有浏览器的设备上完成登录的共享屏幕设备。

如果你有能保护 client-auth 私钥的机密后端,优先考虑 Connect 浏览器轮询。如果客户端拥有 Steam ticket 或预签发 AccessKey 这样的平台凭据,使用 Native direct-issue

原始端点契约见 Device API 参考