Skip to content

OAuth 授权接入

本文档说明 Cyber Hub 作为 OAuth 授权服务时,第三方应用如何接入授权码模式、如何换取 token,以及当前实现限制。登录方式本身见 docs/login-methods.md

总览

Cyber Hub 可以让第三方应用使用 Cyber Hub 账号登录。推荐接入方式是授权码模式:第三方应用把用户跳转到 Cyber Hub 登录页,用户登录并同意授权后,Cyber Hub 带着 code 回跳第三方回调地址,第三方服务端再用 code + client_id + client_secret 换 token。

主流程:

  1. 第三方应用准备 client_idclient_idclient_secret 和回调地址。
  2. 第三方前端跳转到 Cyber Hub 登录页。
  3. 用户在 Cyber Hub 登录并同意授权。
  4. Cyber Hub 生成授权码,并回跳第三方回调地址。
  5. 第三方服务端用授权码换 access token 和 refresh token。
  6. 第三方用 access token 调用 Cyber Hub API 或获取当前用户信息。

准备应用信息

第三方应用需要先在 Cyber Hub 创建应用,拿到以下信息:

字段说明
client_id应用 ID,对应应用记录的 id
client_secret应用密钥,只在创建或重置密钥时明文返回
callbackUrl默认回调地址;授权请求未传 redirect_uri 时使用它
homeUrl应用首页地址,主要用于应用管理展示

应用相关接口:

http
POST /account/api/v1/application/info
GET /account/api/v1/application/info?id=<client_id>
PUT /account/api/v1/application/info
PUT /account/api/v1/application/info/secret?id=<client_id>
GET /account/api/v1/application/info/simple?id=<client_id>

普通应用详情接口会把 secret 脱敏为空;密钥丢失后不能查询明文,只能重置。

授权码流程

第三方前端跳转到 Cyber Hub 登录页:

text
/cyberhub/web/login?client_id=<client_id>&response_type=code&scope=user&state=<state>&redirect_uri=<callback>

参数说明:

参数必填说明
client_id第三方应用 ID
response_type建议传当前授权码模式传 code;服务端目前没有严格校验该字段
scope建议传当前通常传 user;服务端暂未按 scope 裁剪权限
state强烈建议第三方生成并校验,用于防 CSRF 和串联登录上下文
redirect_uri第三方回调地址;为空时使用应用 callbackUrl

用户在 Cyber Hub 登录。账号密码、2FA、手机、邮箱、企业微信入口会继续保留原查询参数。

登录成功后,前端进入授权确认状态,并调用授权接口:

http
POST /account/api/v1/oauth/authorize
Authorization: Bearer <CyberHub accessToken>
Content-Type: application/json

请求体:

json
{
  "client_id": "app-id",
  "response_type": "code",
  "scope": "user",
  "state": "opaque-state",
  "redirect_uri": "https://third.example.com/oauth/callback"
}

响应:

json
{
  "redirectUri": "https://third.example.com/oauth/callback?code=authorization-code&state=opaque-state"
}

Cyber Hub 前端跳转到 redirectUri。第三方回调地址收到 codestate 后,必须先校验 state

第三方服务端用授权码换 token:

http
POST /account/api/v1/oauth/token
Content-Type: application/json

请求体:

json
{
  "grant_type": "authorization_code",
  "code": "authorization-code",
  "client_id": "app-id",
  "client_secret": "app-secret",
  "redirect_uri": "https://third.example.com/oauth/callback"
}

响应:

json
{
  "access_token": "access-token",
  "expires_in": 604800,
  "refresh_token": "refresh-token",
  "token_type": "Bearer"
}

第三方用 access token 获取当前用户:

http
GET /account/api/v1/oauth/user
Authorization: Bearer <access_token>

用户信息会包含用户基础字段、角色、token 信息和可用的第三方账号信息。字段以 model.OauthUserInfo 为准,常用字段包括 iduserIdusernamenamenickNamedepartmentIddepartmentNameemailmobilerolesaccessTokenrefreshToken

刷新和校验 token

OAuth 授权码换出的 token 和普通登录 token 使用同一套有效期:

token有效期说明
access token7 天第三方调用 Cyber Hub API 时通过 Authorization: Bearer <token> 携带
refresh token30 天过期前可换新 access/refresh token

刷新 token:

http
POST /account/api/v1/oauth/refreshToken
Content-Type: application/json

请求体:

json
{
  "refreshToken": "refresh-token"
}

校验当前 access token 是否有效:

http
GET /account/api/v1/oauth/token
Authorization: Bearer <access_token>

有效时返回:

json
{
  "message": "success"
}

兼容的密码模式

/account/api/v1/oauth/token 还支持兼容的密码模式:

http
POST /account/api/v1/oauth/token
Content-Type: application/json

请求体:

json
{
  "grant_type": "password",
  "client_id": "app-id",
  "username": "admin",
  "password": "plain-password"
}

密码模式会直接用用户名密码换 token,不需要 client_secret。这只是历史兼容能力,不推荐第三方新接入优先使用;新接入请使用授权码模式。

当前实现限制

  • 授权码有效期为 5 分钟。
  • 授权码换 token 时会校验 client_secret,但当前没有校验 redirect_uri 必须等于应用 callbackUrl 或授权时的 redirect_uri
  • scope 当前没有真正参与权限裁剪,接口权限仍由 Cyber Hub 用户角色决定。
  • response_type 当前由前端透传,服务端没有严格限制必须为 code
  • 第三方必须自己校验 state,并限制自己的回调入口,别依赖 Cyber Hub 当前实现替你防开放重定向。