O OauthGo

第三方登录接入文档

为其他目标站点提供第三方登录聚合服务。以下两套接口可任选其一接入:
彩虹聚合登录协议(/connect.php,兼容彩虹官方)与自研 REST 风格接口(/api/v1/oauth/*)。

彩虹聚合登录协议

兼容彩虹聚合登录(u.cccyun.cc)的接入方式,目标站点通过 appid / appkey 调用本平台接口完成第三方登录。统一返回 {code, msg, ...}: code=0 成功,code=1 失败,code=2 登录未完成。 接口访问根路径 /connect.php(/api/connect.php 为等价别名), 支持 GET / POST,参数可放查询串或 application/x-www-form-urlencoded 表单体。

接入流程

1
目标站点跳转 connect.php?act=login,携带 appid/appkey/type/redirect_uri,获取第三方授权地址。
2
目标站点将用户重定向到返回的 url,引导用户在第三方平台完成授权。
3
授权完成后平台 302 跳回 redirect_uri,并携带 type、code、sign 三个参数(sign 覆盖 type+code,可服务端二次校验)。
4
目标站点调用 connect.php?act=callback,用 code 换取用户信息(一次性),完成登录。

接口:/connect.php

参数必填说明
act是动作:login / callback / query
appid是应用 ID
appkey是应用密钥
type是登录类型,见下方「类型对照表」
redirect_uriact=login 时必填登录完成后的回跳地址,域名须在应用白名单内
codeact=callback 时必填回调携带的授权码(一次性)
social_uidact=query 时必填第三方平台用户唯一标识

1. 发起登录(act=login)

GET /connect.php?act=login&appid=10001&appkey=your_appkey&type=gitee&redirect_uri=https%3A%2F%2Fexample.com%2Fcallback
{ "code": 0, "msg": "succ", "type": "gitee",
  "url": "https://gitee.com/oauth/authorize?client_id=xxx&redirect_uri=xxx&state=xxx",
  "qrcode": "" }

返回的 url 即为第三方授权地址(已附带一次性 state),目标站点直接 302 跳转即可。

2. 回调(由平台 302 跳回)

用户完成授权后,平台自动跳转到目标站点的 redirect_uri,并追加以下参数:

https://example.com/callback?type=gitee&code=xxxx&sign=xxxx

3. 换取用户信息(act=callback)

GET /connect.php?act=callback&appid=10001&appkey=your_appkey&type=gitee&code=xxxx
{ "code": 0, "msg": "succ", "type": "gitee",
  "access_token": "xxxx",
  "social_uid": "123456",
  "faceimg": "https://avatar.example.com/1.png",
  "nickname": "张三",
  "location": "广东深圳",
  "gender": "男",
  "ip": "1.2.3.4" }

若 code 已使用、过期或登录未完成,返回 code=2:

{ "code": 2, "msg": "未完成登录", "type": "gitee" }

4. 按 social_uid 查询(act=query)

用于目标站点在本地用户登录时校验第三方 UID 是否已绑定,无需携带 code:

GET /connect.php?act=query&appid=10001&appkey=your_appkey&type=gitee&social_uid=123456
{ "code": 0, "msg": "succ", "type": "gitee",
  "social_uid": "123456",
  "faceimg": "https://avatar.example.com/1.png",
  "nickname": "张三",
  "location": "广东深圳",
  "ip": "1.2.3.4" }

类型对照表

type 参数第三方平台
qqQQ 互联
wx微信开放平台
alipay支付宝开放平台
sina微博开放平台
baidu百度开放平台
douyin抖音开放平台
dingtalk钉钉开放平台
giteeGitee(码云)
wework企业微信

兼容模式(compat)的 type 也接受渠道名本身(如 wechat、gitee); REST / OAuth2 模式仅使用渠道名(provider name),见「登录渠道」页中的渠道标识。

REST 风格接口

自研 REST 风格登录接口,请求与响应均为 JSON,统一返回 {code, message, data}。 登录接口(/api/v1/oauth/login)明文校验 appid/appkey;信息接口 (userinfo / query)只传 appid,通过服务端 MD5 签名校验身份,避免 appkey 泄漏。

接入流程

1
目标站点调用 POST /api/v1/oauth/login,携带 appid/appkey/type/redirect_uri,获取第三方授权地址。
2
用户授权完成后平台 302 跳回 redirect_uri,携带 type、code、sign。
3
目标站点调用 POST /api/v1/oauth/userinfo,用 code + sign 换取用户信息(一次性),完成登录。

签名规则

信息接口使用 MD5 签名:将接口相关参数按 key 升序拼接为 k1=v1&k2=v2,末尾追加 &key=<appkey>,整体取 MD5(小写)。

以 userinfo 为例,参数为 appid / type / code:
原串 = appid=10001&code=xxxx&type=gitee&key=your_appkey
sign = md5(原串)
接口签名参与参数
POST /api/v1/oauth/userinfoappid、type、code
POST /api/v1/oauth/queryappid、type、social_uid

1. 发起登录

POST /api/v1/oauth/login,请求体(JSON):

{ "appid": "10001", "appkey": "your_appkey", "type": "gitee",
  "redirect_uri": "https://example.com/callback" }
{ "code": 0, "message": "success",
  "data": { "url": "https://gitee.com/oauth/authorize?client_id=xxx&redirect_uri=xxx&state=xxx",
            "type": "gitee" } }

用户授权完成后,平台 302 跳回 redirect_uri:

https://example.com/callback?type=gitee&code=xxxx

2. 换取用户信息

POST /api/v1/oauth/userinfo,请求体(JSON):

{ "appid": "10001", "code": "xxxx", "type": "gitee",
  "sign": "32 位 MD5 小写" }
{ "code": 0, "message": "success",
  "data": { "type": "gitee", "openid": "123456", "unionid": "u_8888",
            "nickname": "张三", "avatar": "https://avatar.example.com/1.png",
            "email": "zhangsan@example.com", "gender": "男",
            "location": "广东深圳", "access_token": "xxxx", "ip": "1.2.3.4" } }

3. 按 UID 查询用户

POST /api/v1/oauth/query,请求体(JSON):

{ "appid": "10001", "type": "gitee", "social_uid": "123456",
  "sign": "32 位 MD5 小写" }
{ "code": 0, "message": "success",
  "data": { "type": "gitee", "openid": "123456", "nickname": "张三",
            "avatar": "https://avatar.example.com/1.png",
            "location": "广东深圳", "ip": "1.2.3.4" } }

4. 获取已启用渠道

GET /api/oauth/providers,公开接口,无需鉴权:

{ "code": 0, "message": "success",
  "data": [ { "name": "gitee", "display_name": "Gitee", "category": "social" } ] }

错误码

code含义
0成功
1业务失败(message 中给出具体原因)
2登录未完成(code 无效 / 已使用)

标准 OAuth2 / OIDC 授权服务器

本平台同时可作为标准的 OAuth2 / OIDC 授权服务器(authorization code flow), 供任意 OIDC / OAuth2 客户端接入(如使用 oidc-client、Keycloak、Auth0 等生态)。 应用凭证:appid = client_id,appkey = client_secret。 在「应用管理」中把模式设为 oauth2 / compat 并配置「OAuth2/OIDC 回调地址」(按 scheme+host+path 匹配,忽略 query,每行一个)。 接入方自带参数(如 state / app_id)可在「接入示例参数」里逐行配置,仅用于生成示例地址,不参与校验。

端点一览

端点说明
GET/POST /authorize授权端点(response_type=code,支持 PKCE;OIDC Discovery 发布地址)
POST /token令牌端点(authorization_code / refresh_token)
GET/POST /userinfo受保护资源:Bearer access_token 换取用户信息(按 scope 过滤 claims)
GET /jwksid_token(RS256)验签公钥(kid=oauthgo-rsa-1)
POST /revoke撤销 refresh_token / access_token(RFC 7009)
POST /introspect令牌内省(RFC 7662),保护资源方用 client 凭据校验令牌
GET /.well-known/openid-configurationOIDC Discovery(位于 issuer 根路径,主流 SDK 自动发现)
GET /.well-known/oauth-authorization-serverOAuth2 Authorization Server Metadata(RFC 8414)

接入流程

1
目标站点跳转 /api/oauth2/authorize,携带 client_id/appid、redirect_uri、state,可选 scope、PKCE code_challenge。
2
未指定 type 时平台返回「选择登录渠道」授权页;带 type=gitee 等渠道名时直接跳转第三方授权。
3
用户在渠道完成授权后,平台 302 跳回 redirect_uri?code=...&state=...。
4
目标站点在服务端用 code + client_secret/appkey 调 /token 换取 access_token / refresh_token / id_token,再调 /userinfo 获取用户信息。

端点全部发布在 issuer(本站 HOST)根路径 下,与 OIDC Discovery 规范一致;旧前缀 /api/oauth2/* 仍作为兼容别名可用。

平台账号登录(IDP / CAS)

未指定 type 的授权页提供「使用 OauthGo 账号」登录:支持账号密码与 Passkey / WebAuthn 无密码登录。登录成功后平台直接为该账号签发授权码回跳目标站点,实现以平台账号为身份源的单点登录(SSO)。

1. 发起授权

应用须先配置「OAuth2/OIDC 回调地址」(完整 URL,按 scheme+host+path 匹配,忽略 query)。client_id / redirect_uri 兼容 appid、redirect_url 等非标准命名。type 可选:渠道名(provider name,如 wechat / gitee / qq / oauth2)。

https://your-host/authorize?response_type=code&client_id=10001&redirect_uri=https%3A%2F%2Fexample.com%2Foauth%2Fcallback&scope=openid%20profile&state=abc123

2. 授权成功回跳

https://example.com/oauth/callback?code=xxxx&state=abc123

3. 换取令牌

客户端认证支持表单(client_id + client_secret)或 HTTP Basic;应用在「应用管理」中开启「签发刷新令牌」时返回 refresh_token。

curl -X POST https://your-host/token \
  -d "grant_type=authorization_code" \
  -d "code=xxxx" \
  -d "client_id=10001" \
  -d "client_secret=your_appkey" \
  -d "redirect_uri=https://example.com/oauth/callback"
{ "access_token": "xxxx", "token_type": "Bearer", "expires_in": 7200,
  "refresh_token": "xxxx", "scope": "openid profile",
  "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Im9hdXRobmctcnNhLTEifQ.xxx.yyy" }

4. 获取用户信息

curl https://your-host/userinfo -H "Authorization: Bearer ACCESS_TOKEN"
{ "sub": "12", "name": "张三", "preferred_username": "zhangsan",
  "picture": "https://avatar.example.com/1.png", "email": "zhangsan@example.com",
  "scope": "openid profile",
  "accounts": [ { "provider": "wechat", "openid": "oXXXX", "unionid": "uXXXX", "nickname": "张三" } ] }

sub 为该平台稳定用户标识;accounts 列出其绑定的第三方账号(聚合场景可直接取 openid / unionid)。

安全特性

能力说明
PKCEauthorize 支持 code_challenge + code_challenge_method=S256|plain,token 时以 code_verifier 校验
id_tokenscope 含 openid 时签发 RS256 JWT,验签公钥见 /jwks(kid=oauthgo-rsa-1)
refresh_token轮换制,旧令牌立即失效;支持 /api/oauth2/revoke 主动撤销
state / nonce授权码回跳原样带回,防 CSRF;id_token 支持 nonce 校验
一次性授权码授权码有效期 10 分钟,仅可交换一次