1. OAuth
ShangCloud
  • ShangCloud简介
  • 立项一周年庆祝
  • v3
    • V3设计理念
    • 扩展使用教程
    • 云变量
      • 接口设计
      • 读取变量
      • 创建或更新变量
      • 删除变量
      • 用户变量操作 (读/写/删)
    • 社区作品ID获取教程
      • 40code
      • ZeroCat (Moonrend)
      • CCW(共创世界)
      • AstraEditor & 02engine & Bilup
    • OAuth
      • 设备授权登录
      • 获取或刷新 AccessToken
        POST
    • MMO联机
      • 说明
      • TCP/UDP协议联机
      • 创建房间
      • 加入已有房间
      • 设置房间配置
      • 设置房间额外数据(键值对)
      • 获取房间所有额外数据
      • 删除房间额外数据中的指定键
      • 强制踢出房间内指定用户
      • 查询指定房间的当前人数
    • 娱乐功能
      • 随机图
    • 扩展API
      • QQ消息推送
      • 群推送接口
      • IP查询
    • Q&A
      • 40code作品绑定教程
      • ZeroCat作品绑定教程
      • 时间同步
      • 未绑定作品
      • AstraEditor & 02engine & Bilup
    • 健康监控
      • 平台存活状态
      • MMO 系统状态
      • 平台统计数据
    • 云函数
      • 初步设计
  • v2
    • v2
    • 账号操作
      • 登陆
      • 获取用户信息
      • 绑定40code账户
    • 数据库部分
      • 新建数据库
      • 删除数据库
      • 读取数据库
      • 写入数据库
      • 获取数据库列表
      • 重置数据库
    • 状态获取
      • 服务器总占用
  • v1
    • v1
    • 账号操作
      • 管理员
        • 创建新用户
        • 删除用户
        • 设置管理员
        • 获取用户列表
        • 封禁用户
        • 解封用户
      • 普通用户
        • 登录
        • 更改密码
      • 游客
        • 获取用户状态
        • 注册
    • API部分
      • 获取时间戳
      • 获取版本号
      • 邮件验证码
      • 发送HTTP请求
    • 数据库部分
      • 新建数据库
      • 删除数据库
      • 读取数据库
      • 写入数据库
      • 更改数据库权限
      • 获取数据库列表
    • MySQL接口
    • 服务器状态
      • 获取CPU占用
      • 获取总内存
      • 获取使用中内存
      • 获取指定硬盘总容量
      • 获取指定硬盘使用容量
      • 获取内存占用率
      • 获取指定硬盘占用率
      • 设置风扇转速
      • 设置风扇为手动模式
      • 服务器总状态
  • MMO
    • 接入文档
    • 加入MMO房间
      POST
    • 创建MMO房间
      POST
  • 所有操作
    GET
  • 数据模型
    • Schemas
      • AccessTokenInvalid
      • SuccessResponse
      • BadResponse
      • NoPowerResponse
      • NotFoundResponse
      • ServerErrorResponse
    • 极验数据
    • RoomResult
    • VariableResponse
    • StatusResponse
    • ErrorResponse
    • Error
    • MmoStatsResponse
    • SuccessStatusResponse
    • PlatformStatsResponse
  1. OAuth

设备授权登录

设备授权登录(Device Authorization Grant)#

ShangCloud 支持 RFC 8628 设备授权码流程(Device Authorization Grant),适用于:
命令行工具(CLI)
无图形界面 / 不便完成浏览器重定向的客户端
输入受限设备(智能电视、嵌入式终端等)
典型体验与 GitHub CLI、gcloud auth login 类似:
1.
CLI 向服务器申请一对码(device_code + user_code)
2.
用户在浏览器打开验证页,输入 user_code 并登录、确认授权
3.
CLI 轮询 Token 端点,直到拿到 access_token(及可选的 refresh_token / id_token)

前置条件#

1.
在 ShangCloud 开发者中心创建应用,获取 Client ID(client_id)
2.
设备码流程不依赖 redirect_uri,无需为 CLI 配置回调地址
3.
机密客户端可附带 client_secret
4.
免 AppSecret 的公开客户端:需在应用编辑页开启「允许公开客户端 PKCE」,并在申请/换 token 时使用 PKCE
Issuer / 基址可通过 OIDC 发现获取:
关键字段:
字段说明
device_authorization_endpoint设备授权请求端点
token_endpoint令牌端点(轮询)
grant_types_supported含 urn:ietf:params:oauth:grant-type:device_code
生产环境示例基址:https://api.yearnstudio.cn

流程总览#

┌─────────┐                     ┌──────────────┐                    ┌────────────┐
│   CLI   │                     │  ShangCloud  │                    │ 用户浏览器  │
└────┬────┘                     └──────┬───────┘                    └─────┬──────┘
     │  POST /oauth/device_authorization │                                │
     │  client_id, scope                 │                                │
     │──────────────────────────────────>│                                │
     │  device_code, user_code,          │                                │
     │  verification_uri, interval       │                                │
     │<──────────────────────────────────│                                │
     │                                   │                                │
     │  展示 user_code + 打开验证页 URL    │                                │
     │───────────────────────────────────┼───────────────────────────────>│
     │                                   │  登录 + 输入 user_code + 同意   │
     │                                   │<───────────────────────────────│
     │                                   │  标记授权成功                   │
     │                                   │                                │
     │  轮询 POST /oauth/token           │                                │
     │  grant_type=device_code           │                                │
     │──────────────────────────────────>│                                │
     │  authorization_pending / token    │                                │
     │<──────────────────────────────────│                                │

1. 请求设备码#

请求#

参数必填说明
client_id是应用 Client ID
scope否权限范围,空格或逗号分隔。默认 openid
client_secret条件默认必填;应用开启「公开客户端 PKCE」且同时提交 code_challenge 时可省略
code_challenge条件PKCE challenge。免 secret 时必填;有 secret 时可选
code_challenge_method否S256(推荐)或 plain,默认 S256
也支持 HTTP Basic 传递客户端凭证:Authorization: Basic base64(client_id:client_secret)。
公开客户端 PKCE:应用设置 allow_public_pkce 默认关闭。开启后,设备码 / 授权码流程可在使用 PKCE 时不传 client_secret。若申请时带了 code_challenge,轮询时必须带匹配的 code_verifier。

成功响应 200#

{
  "device_code": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
  "user_code": "ABCD-EFGH",
  "verification_uri": "https://api.yearnstudio.cn/oauth/device",
  "verification_uri_complete": "https://api.yearnstudio.cn/oauth/device?user_code=ABCD-EFGH",
  "expires_in": 900,
  "interval": 5
}
字段说明
device_code仅保存在 CLI 侧,用于轮询换取令牌,切勿展示给用户
user_code展示给用户输入的短码(格式 XXXX-XXXX)
verification_uri用户应打开的验证页
verification_uri_complete已预填 user_code 的链接(可直接打开)
expires_in有效期(秒),默认 900(15 分钟)
interval建议轮询间隔(秒),默认 5

错误响应#

{
  "error": "invalid_client",
  "error_description": "Unknown client_id"
}
常见 error:invalid_client、invalid_request。

2. 用户在浏览器完成授权#

1.
引导用户打开 verification_uri 或 verification_uri_complete
2.
若未登录 ShangCloud,会先跳转登录
3.
输入 user_code(若链接已预填则跳过)
4.
确认应用名称与权限后点击 授权 或 拒绝
验证页路径:
GET  /oauth/device
GET  /oauth/device?user_code=ABCD-EFGH
POST /oauth/device   # 表单:user_code, action=lookup|allow|deny
需要用户 Session(已登录)。

3. CLI 轮询换取令牌#

请求#

参数必填说明
grant_type是固定为 urn:ietf:params:oauth:grant-type:device_code
device_code是步骤 1 返回的设备码
client_id是应用 Client ID
client_secret条件默认必填;应用开启公开 PKCE 且步骤 1 使用了 PKCE 时可省略
code_verifier条件若步骤 1 使用了 PKCE,则必填

用户尚未授权(继续轮询)#

HTTP 400:
{
  "error": "authorization_pending",
  "error_description": "The authorization request is still pending"
}
按 interval 秒等待后再次请求。

轮询过快#

HTTP 400:
{
  "error": "slow_down",
  "error_description": "Polling too frequently, increase interval"
}
将间隔 至少 +5 秒 后再试。

用户拒绝#

{
  "error": "access_denied",
  "error_description": "The end-user denied the authorization request"
}

码过期#

{
  "error": "expired_token",
  "error_description": "The device_code has expired"
}
需重新从步骤 1 开始。

成功响应 200#

{
  "access_token": "<JWT>",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "<opaque>",
  "scope": "openid profile",
  "id_token": "<JWT>"
}
access_token:RS256 JWT,有效期 1 小时
refresh_token:不透明串,约 30 天,可用于 grant_type=refresh_token 续期
当 scope 包含 openid 时返回 id_token
之后调用受保护 API:

最小 CLI 示例(Python + PKCE)#

curl 片段#


Scope 说明#

设备码流程与授权码流程使用同一套 scope。常见值:
Scope含义
openidOIDC;会签发 id_token,可识别用户
profile用户公开资料(昵称、头像等)
email / user:email邮箱相关
user:basic用户基本信息
var:io云变量读写
mmo多人联机
多个 scope 用空格分隔:openid profile user:basic。
用户信息端点:

安全建议#

1.
device_code 仅保存在进程内存,不要写入日志或发给用户
2.
user_code 可展示,有效期短(默认 15 分钟),一次性使用
3.
轮询务必遵守 interval,收到 slow_down 后加大间隔
4.
验证页展示应用名与权限列表,提醒用户确认是否本人操作
5.
机密客户端使用 client_secret;无法保存密钥的 CLI 需在开发者中心开启「公开客户端 PKCE」,并使用 PKCE(S256)
6.
拿到的 access_token / refresh_token 按密钥保管,勿提交到仓库
7.
code_verifier 仅保存在 CLI 进程内,不要写入日志
8.
未开启 allow_public_pkce 时,无 secret 的请求一律拒绝(即使带了 PKCE)

与授权码流程的对比#

授权码 + PKCE设备授权码
适用场景Web / 桌面(可打开回调)CLI / 输入受限设备
是否需要 redirect_uri是否
用户交互浏览器跳转回应用浏览器输入短码
Token 获取用 code 换 token用 device_code 轮询
grant_typeauthorization_codeurn:ietf:params:oauth:grant-type:device_code
两种流程签发的 Access Token / Refresh Token / ID Token 格式与权限模型一致,可互换使用于同一套 API。

错误码速查(Token 轮询)#

error含义CLI 行为
authorization_pending用户尚未完成授权等待 interval 后重试
slow_down轮询过快间隔 +5s 后重试
access_denied用户拒绝终止并提示
expired_token设备码过期重新申请设备码
invalid_grant码无效或不属于该 client终止
invalid_client客户端凭证错误检查 client_id / secret

发现文档示例#

响应中应包含:
{
  "device_authorization_endpoint": "https://api.yearnstudio.cn/oauth/device_authorization",
  "grant_types_supported": [
    "authorization_code",
    "refresh_token",
    "urn:ietf:params:oauth:grant-type:device_code"
  ],
  "code_challenge_methods_supported": ["plain", "S256"]
}

参考#

RFC 8628 — OAuth 2.0 Device Authorization Grant
ShangCloud OIDC 发现:/.well-known/openid-configuration
用户信息:GET /oauth/userinfo
修改于 2026-07-24 12:09:35
上一页
AstraEditor & 02engine & Bilup
下一页
获取或刷新 AccessToken
Built with