OAuth 开放登录
让用户使用 800BUS 账号登录你的应用 · 第三方开发者接入文档
OAuth 2.0 · Authorization Code + PKCE (S256)
800BUS 面向第三方应用提供标准 OAuth 2.0 授权码模式登录能力,强制启用 PKCE(S256),支持刷新令牌轮换与令牌吊销。
接入采用申请制:请通过下方联系方式提交应用信息,审核通过后发放 client_id,再按本文档接入。
一、接入准备
- 创建应用:通过下方联系方式提供应用名称、简介、回调地址,由本站管理员在后台创建
- 获取凭据:创建后会发放 client_id;机密应用(有服务端)另发放 client_secret,纯前端(SPA / 无后端)应用为公开应用,仅凭 PKCE 即可接入
- 回调地址:支持注册多个,请求时必须与注册地址完全一致(逐字节精确匹配,不允许通配)
- 域名白名单(可选):限制允许发起令牌请求的来源域名,支持 *.example.com 通配符;留空则不限制。token / userinfo / revoke 端点会校验请求的 Origin(缺失时回退 Referer),不在白名单内返回 403
二、端点一览
授权端点(浏览器跳转)GET https://800bus.cn/oauth/authorize/
令牌端点(服务端 / 前端直连)POST https://800bus.cn/oauth/token/
用户信息端点GET|POST https://800bus.cn/oauth/userinfo/?client_id={client_id}
令牌吊销端点(RFC 7009)POST https://800bus.cn/oauth/revoke/
实名状态查询端点(需 realname scope)GET|POST https://800bus.cn/oauth/realname/?client_id={client_id}
注意路径末尾的斜杠:目录请求会被 301 补斜杠导致 POST 降级,请始终携带尾斜杠。
三、授权流程
1生成 PKCE 凭据(每次登录随机生成,verifier 保密保存在自己侧):
// code_verifier:43-128 位 base64url 随机串
// code_challenge = BASE64URL(SHA256(code_verifier))
const verifier = base64url(crypto.getRandomValues(new Uint8Array(32)));
const challenge = base64url(await crypto.subtle.digest(
'SHA-256', new TextEncoder().encode(verifier)));
2跳转授权端点(携带 state 防 CSRF):
https://800bus.cn/oauth/authorize/
?response_type=code
&client_id={client_id}
&redirect_uri={注册的回调地址,URL 编码}
&scope=openid profile email
&state={随机值}
&code_challenge={challenge}
&code_challenge_method=S256
response_type 仅支持 code。用户未登录时会先进入 800BUS 登录页,登录后自动回到确认页;首次授权会展示授权确认页,由用户勾选同意。
3接收回调:用户同意后浏览器跳回 redirect_uri,附上 code 与原样返回的 state(请先校验 state)。用户拒绝则返回 error=access_denied。
4换取令牌(application/x-www-form-urlencoded):
POST https://800bus.cn/oauth/token/
grant_type=authorization_code
code={回调收到的授权码}
redirect_uri={与第 2 步逐字节一致}
client_id={client_id}
client_secret={机密应用必填;公开应用省略}
code_verifier={第 1 步的 verifier}
5调用成功返回:
{
"access_token": "…",
"refresh_token": "…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "openid profile email"
}
四、获取用户信息
令牌两种传法均可:GET + Authorization: Bearer 头,或 POST 表单 access_token(简单请求,不触发 CORS 预检,推荐纯前端使用):
方式 AGET https://800bus.cn/oauth/userinfo/?client_id={client_id}
Authorization: Bearer {access_token}
方式 BPOST https://800bus.cn/oauth/userinfo/?client_id={client_id}
Content-Type: application/x-www-form-urlencoded
access_token={access_token}
返回字段(按授权的 scope 返回):
- sub:用户数字 ID(字符串,始终返回)
- name / preferred_username / picture:昵称 / 用户名 / 头像 URL(需 profile)
- email:注册邮箱(需 email)
五、scope 与令牌有效期
- openid:获取用户 ID(sub),必选基础权限
- profile:昵称、用户名、头像
- email:注册邮箱
- realname:实名状态(是否已绑定手机号,仅返回 1/2,不提供号码本身,需在应用授权范围中配置)
- 授权码:120 秒内有效,仅可使用一次,重复使用按规范视为重放攻击
- access_token:3600 秒
- refresh_token:自首次签发起 30 天内有效;刷新会轮换出新令牌但不延长总有效期,到期后需引导用户重新授权
实名状态查询(需 realname scope,令牌传法与 userinfo 相同):
POST https://800bus.cn/oauth/realname/?client_id={client_id}
access_token={access_token}
已绑定手机号 → {"realname": 1}
未绑定 → {"realname": 2}
令牌缺少 realname 权限 → 403 {"error":"insufficient_scope", …}
六、刷新与吊销令牌
刷新(返回新的 access_token 与 refresh_token,旧的 refresh 即刻作废)POST https://800bus.cn/oauth/token/
grant_type=refresh_token
refresh_token={当前的 refresh_token}
client_id={client_id}
client_secret={机密应用必填}
scope={可选,必须是原授权范围的子集}
吊销(幂等,一律返回 200 {"revoked":true})POST https://800bus.cn/oauth/revoke/
token={access_token 或 refresh_token}
client_id={client_id}
client_secret={机密应用必填}
刷新令牌轮换与复用检测:每次刷新都会作废旧 refresh_token 并签发新的。已作废的令牌再次出现会被判定为令牌泄露,该用户在该应用下的全部令牌将被立即吊销。请务必原子化保存最新 refresh_token。
吊销 refresh_token 会同时吊销同族全部令牌;吊销 access_token 仅使该条失效。用户登出时建议调用吊销端点。
七、安全要求
- 必须校验 state:回调时核对 state 是否与发起时一致,防止 CSRF
- code_verifier 绝不外传:仅用于 token 端点,不要写入 URL 或日志
- 机密应用妥善保管 client_secret:只允许在服务端使用,公开应用切勿在客户端硬编码任何 secret
- 错误响应:所有端点返回标准 JSON {"error":"…","error_description":"…"}(如 invalid_request / invalid_grant / invalid_client / invalid_scope / unsupported_grant_type)
- 登录环境绑定:为防会话转移,用户登录流程与其首次访问环境(IP / 浏览器信息)绑定,环境变化时用户会看到「请重新发起登录」提示——这是预期安全行为,引导用户从应用重新发起即可
- 违规滥用(批量采集、骚扰用户、超出授权范围使用数据)将被直接停用应用并吊销全部令牌
八、用户权利与数据边界
- 用户可在 800BUS「个人设置 → 已授权的第三方应用」随时查看并一键解除授权,解除后该应用全部刷新令牌立即失效
- 应用仅能获取用户在确认页勾选授权的信息,不得用于授权范围以外的用途,不得转售或共享给第三方
- 用户注销、被封禁或应用被停用后,相关令牌自动失效
数据处理规则另见 《隐私政策》 与 《用户协议》。
九、联系方式
申请接入、变更回调地址、报告安全问题请联系:
十、其他
本文档描述的接口可能随安全策略升级调整,更新后在本页公示。建议开发者在刷新令牌失败(invalid_grant)时统一走重新授权流程,以兼容未来的令牌策略变化。