跳到主要内容

用户信息

GET /api/userinfo

获取当前 Token 对应的用户信息。

频率限制

  • 60 次/分钟(基于请求方 IP,非服务器全局限制)
  • 超限返回 HTTP 429,响应头包含 Retry-After

认证方式

方式一(推荐):Authorization Header

GET https://id.caellab.com/api/userinfo
Authorization: Bearer ACCESS_TOKEN

方式二:查询参数

GET https://id.caellab.com/api/userinfo?access_token=ACCESS_TOKEN
安全提示

查询参数方式会将 Token 暴露在 URL 中(出现在服务器日志、浏览器历史记录中)。生产环境请使用 Header 方式。

Token 验证

系统会对 Token 执行以下检查:

  1. 计算 SHA-512 哈希(兼容旧的 SHA-256 记录)
  2. oauth_access_tokens 表中查找
  3. 验证 revoked = 0expires_at > NOW()
  4. 验证关联的用户 status = 1(未禁用/封禁)

响应字段

返回的字段取决于 Token 的 Scope:

字段类型Scope说明
substringopenid应用级用户标识(32 字符 hex)
idstringopenidsub
usernamestringprofile用户名(用户自定义的唯一标识)
display_namestringprofile昵称
avatarstring/nullprofile头像 URL(webp 格式,可直接 GET)
emailstringemail用户已验证的邮箱地址
email_verifiedbooleanemail邮箱是否已验证

响应示例

scope = openid

{
"sub": "9402013ac8b214059694f64f130da6f2a9a4603e06215f2c6998929eb511ce08",
"id": "9402013ac8b214059694f64f130da6f2a9a4603e06215f2c6998929eb511ce08"
}

scope = openid profile

{
"sub": "9402013ac8b214059694f64f130da6f2a9a4603e06215f2c6998929eb511ce08",
"id": "9402013ac8b214059694f64f130da6f2a9a4603e06215f2c6998929eb511ce08",
"username": "yunyun",
"display_name": "云云",
"avatar": "https://id.caellab.com/assets/avatars/example.webp"
}

scope = openid profile email

{
"sub": "9402013ac8b214059694f64f130da6f2a9a4603e06215f2c6998929eb511ce08",
"id": "9402013ac8b214059694f64f130da6f2a9a4603e06215f2c6998929eb511ce08",
"username": "yunyun",
"display_name": "云云",
"avatar": "https://id.caellab.com/assets/avatars/example.webp",
"email": "[email protected]",
"email_verified": true
}
关于 avatar

avatar 字段返回完整的 URL 地址(webp 格式),你的应用可以直接 GET 该 URL 获取头像图片。

错误响应

Token 无效或已过期(401):

{
"error": "unauthorized",
"error_description": "无效或过期的访问令牌"
}

跨应用隐私保护

sub 字段是应用级别的用户标识。系统通过 user_app_subjects 表为每个应用的每个用户生成独立的 subject_idbin2hex(random_bytes(16)),32 字符 hex)。

这意味着:

  • 用户 A 在应用 X 中的 subabc123...
  • 用户 A 在应用 Y 中的 subdef456...
  • 不同应用无法通过 sub 关联同一用户