跳转到内容

Connect 流程

查看 Markdown

本页讲解 Connect 协议:当应用希望直接控制浏览器登录往返时使用的 Sudomimus 流程。Connect 走 JSON over HTTPS,任何带 HTTP 客户端的后端语言都能使用;下面给出 curl、Node.js、Python、Go 四种示例。

生产代码中,优先使用已有的官方 SDK。可以先选择框架或 API SDK,或直接查看使用 @sudomimus/connect 的 TypeScript API SDK。

如果你做的是原生客户端(桌面、游戏、CLI),见 原生客户端。如果走 OIDC,见 OIDC 接入方。

Tab 全页同步:选一次语言,下面所有代码块都会跟随切换。

开始登录前,请配置所选流程需要的规则和凭据,再由组织 OWNER 激活应用。新应用会保持 DRAFT,直到明确执行激活;登录要求应用为 ACTIVE,且所属组织和扇区均可用。

阶段 发起方 端点 结果
1. Establish 应用后端 connect-api POST /establish { exposureKey, hiddenKey }
2. Authenticate 浏览器 via.sudomimus.com 用户完成一项允许的认证挑战
3. Redeem 应用后端 connect-api POST /redeem { accessToken, refreshToken }
4. Refresh 应用后端 session-api POST /refresh 新 access token 与轮换后的 refresh token

下图展示本页示例采用的标准 CALLBACK 路径:

sequenceDiagram
    autonumber

    participant App as 应用后端
    participant Browser as 用户浏览器
    participant Connect as Connect API
    participant Via as via.sudomimus.com
    participant Session as Session API

    App->>Connect: POST /establish<br/>client-auth JWT + return method
    Connect-->>App: exposureKey + hiddenKey

    Note over App: hiddenKey 只保存在服务端

    App-->>Browser: 302 重定向,携带 exposureKey
    Browser->>Via: 打开托管认证界面

    Note over Browser,Via: 用户完成一项允许的认证挑战

    Via-->>Browser: 302 到应用 callback<br/>exposureKey + confirmationKey
    Browser->>App: GET 应用 callback

    App->>Connect: POST /redeem<br/>exposureKey + hiddenKey + confirmationKey
    Connect-->>App: accessToken + refreshToken

    App->>Session: GET 应用 JWKS
    Session-->>App: 公钥验证材料
    Note over App: 在本地验证 access token

    loop access token 过期前
        App->>Session: POST /refresh<br/>当前 refreshToken
        Session-->>App: 新 accessToken + 轮换后的 refreshToken
    end

三个参与方各自承担不同责任:

  • 应用后端签名 /establish、保存 hiddenKey、兑换已完成的 inquiry,并验证最终令牌。
  • 浏览器把 exposureKey 带到托管认证界面,但永远看不到 hiddenKey。
  • via.sudomimus.com执行通行密钥、邮箱验证码、OAuth 或联合登录挑战,只有认证成功后才创建 confirmationKey。

前三个阶段只属于 Connect。refresh、introspection、logout 和 revoke-all 是普通应用会话生命周期,由共享的 Session API 承接。OIDC 使用 authorization code + PKCE;原生 direct-issue 则在一次请求中交换 Steam ticket、AccessKey 或 PublicKey。

后端请求 Connect 开启一次认证会话。返回里会同时给出 exposure key(要传给浏览器)和 hidden key(留在服务器)。

终端窗口
curl -X POST https://connect-api.sudomimus.com/establish \
-H "Content-Type: application/json" \
-H "Authorization: SudomimusClientJWT $SUDOMIMUS_CLIENT_AUTH_JWT" \
-d '{
"applicationAnchor": "your-application",
"returnMethods": [
{
"type": "CALLBACK",
"payload": { "callbackUrl": "https://your-app.com/auth/callback" }
}
]
}'

把 hiddenKey 与用户的 pending session 绑定存到服务端,然后用 URL 里带上 exposureKey 把用户跳转到 via.sudomimus.com。

2. Authenticate —— 交给 via.sudomimus.com

Section titled “2. Authenticate —— 交给 via.sudomimus.com”

把用户浏览器跳转到 via.sudomimus.com,URL 里带上 exposure key。用户在那里完成通行密钥或邮箱验证码挑战。

# 不发 HTTP —— 你的应用做一次 302:
Location: https://via.sudomimus.com/?exposure-key=<exposureKey>

用户完成挑战后,via.sudomimus.com 会将浏览器跳转回 callbackUrl,并在 URL 中附带 exposure-key 和 confirmation-key 两个查询参数。

在回调处理程序中,将三个密钥一并提交给 Connect,换取访问令牌和刷新令牌。

终端窗口
curl -X POST https://connect-api.sudomimus.com/redeem \
-H "Content-Type: application/json" \
-d '{
"exposureKey": "...",
"hiddenKey": "...",
"confirmationKey": "..."
}'

返回的令牌在通过完整的令牌验证流程前都应视为不透明凭据;验证还包括 typ 与执行主体结构检查。

4. Refresh —— 通过 Session API 维持会话有效

Section titled “4. Refresh —— 通过 Session API 维持会话有效”

在 access token 过期前,把 refresh token 交给 Session API,换取一个新的 access token 和一个新的 refresh token。/refresh 不需要 client-auth JWT。refresh token 会被轮换 —— 你提交的令牌被消费,响应里返回它的替代者。请存下新的 refreshToken 并在下一次刷新时使用它;重复使用已经用过的令牌会导致整个会话被吊销。对同一个令牌近乎同时的并发刷新(例如多个标签页)会被容忍并收敛到同一个会话;只有在替代令牌签发之后再复用才会吊销它。

终端窗口
curl -X POST https://session-api.sudomimus.com/refresh \
-H "Content-Type: application/json" \
-d '{ "refreshToken": "..." }'

会话内省、登出、账户级吊销见 管理会话。

POST /info 根据 anchor 返回某个应用的本地化公开资料。它不需要 client-auth JWT,可以从浏览器或其他不可信上下文中调用。签名密钥由 Session JWKS 端点负责,不属于这个元数据路由。

终端窗口
curl -X POST https://connect-api.sudomimus.com/info \
-H "Content-Type: application/json" \
-d '{ "applicationAnchor": "your-application", "locale": "zh-CN" }'

请使用令牌与验证中说明的应用专属 Session JWKS;缓存与未知 kid 的处理规则由该页统一说明。

当原生客户端能拉起用户的系统浏览器、但又不方便接收回调 URL 时,使用轮询流程:

  1. 客户端后端调用 connect POST /establish(带上应用的 client-auth JWT),声明 STATUS_POLL 返回方法,拿到 { exposureKey, hiddenKey }。
  2. 客户端拉起系统浏览器并打开 https://via.sudomimus.com/?exposure-key=<exposureKey>。
  3. 用户在浏览器中完成通行密钥或邮箱验证码挑战。
  4. 客户端每隔几秒调用一次 connect POST /status-poll,提交 { exposureKey, hiddenKey }。一旦用户完成,轮询会返回 { status: "REALIZED", confirmationKey }。
  5. 客户端将三个密钥提交给 connect POST /redeem,换取 { accessToken, refreshToken }。

这一方案适用于任何带默认浏览器的平台——Windows、macOS、Linux 桌面应用、Electron 等等。应用的 Layer 3 规则中必须允许 STATUS_POLL。

/establish 就是标准的、用 client-auth 签名的 Connect 请求 —— 完整形状见 Web 应用 —— 只是返回方法换成 STATUS_POLL:

终端窗口
curl -X POST https://connect-api.sudomimus.com/establish \
-H "Content-Type: application/json" \
-H "Authorization: SudomimusClientJWT $SUDOMIMUS_CLIENT_AUTH_JWT" \
-d '{
"applicationAnchor": "your-application",
"returnMethods": [ { "type": "STATUS_POLL", "payload": {} } ]
}'
# → { "exposureKey": "exp_...", "hiddenKey": "hid_..." }

随后用这两把 key 每隔几秒轮询一次 /status-poll。轮询不带 client-auth JWT —— 授权它的是对 hiddenKey 的持有:

终端窗口
curl -X POST https://connect-api.sudomimus.com/status-poll \
-H "Content-Type: application/json" \
-d '{
"exposureKey": "exp_...",
"hiddenKey": "hid_..."
}'
# 用户仍在浏览器里鉴权时:
# { "status": "PENDING" }
# 用户完成后:
# { "status": "REALIZED", "confirmationKey": "cnf_..." }

轮询返回 REALIZED 后,将三个密钥提交给 connect POST /redeem,换取访问令牌和刷新令牌。该调用与 Web 流程中的 /redeem 相同。