Skip to main content
Documentation navigation

KAI AUTH / DEVELOPERS

Better Auth 1.7.1Updated Content: Simplified Chinese
View Markdown
On this page

授权码与 PKCE

通过浏览器完成用户登录和授权,再以一次性授权码换取令牌。

发现服务

读取 https://auth.kai.com/.well-known/openid-configuration,要求返回的 issuer 与配置的 https://auth.kai.com 完全一致。使用文档返回的 authorization、token、JWKS 和 UserInfo URL,不猜测 /api 路径。

创建授权事务

每次登录生成高熵随机 state、nonce 和 PKCE code_verifier。code_challenge 是 verifier 的 SHA-256 摘要经 base64url 编码,code_challenge_method 固定 S256。将事务保存到当前浏览器或服务端会话,设置短有效期,消费后立即删除。

GET /api/auth/oauth2/authorize
  ?client_id=YOUR_CLIENT_ID
  &response_type=code
  &redirect_uri=https%3A%2F%2Fapp.example.com%2Foauth%2Fcallback
  &scope=openid%20profile%20email
  &state=RANDOM_STATE
  &nonce=RANDOM_NONCE
  &code_challenge=BASE64URL_SHA256_VERIFIER
  &code_challenge_method=S256

这是纯登录示例,故不携带 resource。若要访问资源服务器,在用户授权阶段发送已获准的准确 resource identifier,并在兑换时保持该授权目标,不能在拿到 code 后扩展资源或 scope。

要求重新验证

确实需要用户重新证明身份时使用标准 prompt=login,或用 max_age 限定最近认证时间。Auth 对已有登录会话提供独立的重新验证与取消流程;完成密码、OTP、Passkey 或 Lark 所需的全部验证后,原地更新会话证据和 auth_time,保留 SID 与已有应用授权,不额外创建会话。普通登录不应无条件强制重新验证。

prompt=none 保持静默语义,无法满足条件时返回协议错误,不打开交互页面。账号安全设置改变导致的令牌撤销与普通重新验证不同,见令牌校验与 claims。

高风险操作的额外验证

应用需要在高风险操作前再次确认当前用户时,创建新的授权码事务,在原有 openid、state、nonce、PKCE 参数之外添加:

acr_values=urn:kai:acr:step-up

这个值请求 KAI 的额外验证策略,不指定验证方式,也不代表某个统一的 MFA 等级。KAI 按账号已配置的安全方式选择流程:只要配置了高等级安全因子就不能退回密码;账号没有配置这类因子时才允许密码。设备暂不可用、验证失败或被限流不会解除该限制。没有可用验证方式时,用户需要先解决账号访问问题。

已登录用户在独立页面完成验证,过程保留当前浏览器会话。普通登录本身不能替代这次额外验证。验证凭据绑定本次应用、用户、浏览器会话和完整授权事务,只能签发一次授权码;其他应用或另一笔 state / nonce 事务不能借用。可同时使用 prompt=login 或 max_age,整个恢复与授权流程保留其绑定,不要求用户反复登录。

回调仍使用应用登记的 redirect_uri,仍须完成标准授权码兑换和 ID token 校验。随后额外检查:

  • acr 必须等于 urn:kai:acr:step-up;
  • kai_step_up.status 为 verified 时表示已完成高等级额外验证,为 password_only 时只表示完成密码验证;由业务方决定密码结果是否足够;
  • auth_time 是这次证明的秒级时间,业务方应检查自己的新鲜度窗口,并确认 iss / sub 与当前业务账号一致。

应用不会获得具体因子、设备或 amr 明细。用户主动取消时返回标准 OAuth 错误;关闭页面、断网或超时可能没有回调,应用应按未完成处理。这些情况都不会签发表示成功的 ID token。prompt=none 在缺少本次已完成证明时返回 interaction_required,未登录时返回 login_required。

刷新令牌不会执行新验证,也不会更新这次结果的 auth_time。需要更新证明时必须重新发起上述授权事务。此结果只证明身份验证完成,不等于用户批准了转账、修改资料等具体业务操作;业务操作及其参数仍由应用自行确认和授权。

完整请求示例、三种结果、字段类型、失败处理和 CLI 边界见额外身份验证。

接收回调

只在本应用登记的回调接收响应。拒绝缺失、重复、不匹配或过期的 state;检查授权响应中的 iss 与预期 issuer 一致。处理 error(例如用户拒绝)时也验证事务。不要把 code、令牌或完整回调 URL 发送到日志或分析服务。

验证成功后立即消费事务,用与授权请求完全相同的 redirect_uri 和原 code_verifier 兑换 code。授权码只可使用一次,失败后重新发起登录。

兑换令牌

向 Discovery 的 token_endpoint POST application/x-www-form-urlencoded:

grant_type=authorization_code
client_id=YOUR_CLIENT_ID
code=AUTHORIZATION_CODE
redirect_uri=https://app.example.com/oauth/callback
code_verifier=ORIGINAL_VERIFIER

public 客户端不发送 secret;confidential 客户端另外使用 HTTP Basic 认证。不要在前端复制 confidential secret,也不要为了方便测试改变现有应用的客户端类型。

响应包含 access_token、token_type、expires_in;有效 scope 含 openid 时提供 ID token,允许 refresh grant 且获准 offline_access 时提供 refresh token。检查实际返回的 scope,资源策略可能缩小权限。

验证身份

用 JWKS 验证 ID token 签名,检查 iss、aud(本应用的 client ID)、exp、nonce,必要时按 OIDC 规范检查 azp 和 at_hash。仅解码 JWT 不等于验证。使用经过验证的 iss 与 sub 识别账号,不以邮箱作为永久主键。

向 UserInfo 发送 Authorization: Bearer ACCESS_TOKEN。其 sub 必须与 ID token 一致。profile、email 控制可读的用户信息,不保证 ID token 内包含所有资料字段。

刷新与退出

refresh token 只在用户已授权 offline_access 时使用;客户端需要支持刷新轮换,成功后使用新返回的 refresh token。不要并行刷新同一授权链,也不要把原始 refresh token 显示在测试报告中。

退出应用和退出 Auth 会话是不同动作。跨应用退出、令牌撤销及回跳请按退出与授权撤销实现。