跳转到主要内容
身份验证功能是新功能。本页的每个调用都只能使用终端用户凭证,或者完全不使用凭证。切勿将您的验证 API 密钥或控制台 token 发送到这些 endpoint。
每个应用都是独立的 OpenID Connect 颁发者(issuer)。颁发者即应用的登录源:
  • 生产应用使用 https://<name>.auth.didit.me,
  • 沙盒应用使用 https://<name>.sandbox.auth.didit.me,
  • 或者您的自定义域名(域名生效后)。
生产环境与沙盒是两个独立的颁发者,各自拥有独立的密钥。将 DIDIT_AUTH_ISSUER 设置为您的颁发者,末尾不要带斜杠;将 DIDIT_APPLICATION_ID 设置为您的应用 ID,token 会以 aud 字段携带该值。您的可发布密钥(publishable key)中编码了颁发者:在 pk_live_ 或 pk_test_ 之后的部分,就是经过无填充 base64url 编码的颁发者。
自定义域名生效后,它会取代默认主机成为颁发者。新 token 会在 iss 中写入该域名,发现文档会将 jwks_uri 指向该域名,您的可发布密钥也会随之变化。在刷新之前,使用默认主机签发的访问 token 调用 GET /session/ 会失败。激活域名时请更新 DIDIT_AUTH_ISSUER;或者在旧 token 于 5 分钟内过期之前,同时接受两个颁发者。
本页涉及的服务器端 endpoint(发现、密钥、token 和会话)记录在身份验证 API 参考中,该参考由 openapi-authentication.json 生成。托管登录页面不在其中。

发现与密钥

颁发者支持以下内容:
  • 响应类型 code,响应模式 query。
  • 授权类型 authorization_code 和 refresh_token。
  • PKCE 方法仅支持 S256。客户端为公开客户端:没有客户端密钥,client_id 即您的应用 ID。
  • 签名算法 ES256(P-256 密钥)。
  • 作用域 openid、email、phone、profile 和 offline_access。
不提供 userinfo、introspection 或 end-session endpoint,也不支持 prompt=none。请使用 GET /session/ 读取并检查会话。

缓存与轮换

两份文档都返回 Cache-Control: public, max-age=300,因此您和共享缓存可以将其保存 5 分钟。每个 IP 地址每分钟允许 1,200 次请求,每小时允许 12,000 次。这一限额远高于登录 endpoint 的速率限制,因为许多后端实例通常共用同一个地址。
  • 每个密钥都有 kid;新密钥 ID 以 k_ 开头。每个 token 都会在 kid 头部中注明其密钥。
  • Didit 每 30 天轮换一次密钥。Didit 会在新密钥开始签名前一天发布该密钥,并在旧密钥停止签名后继续发布它一天。因此,缓存 5 分钟的 JWKS 在轮换期间仍可继续验证。
  • 按 kid 缓存密钥。当 token 包含您没有的 kid 时,重新获取 JWKS,但每分钟最多一次;如果仍找不到该密钥,则拒绝该 token。
  • 当 Didit 吊销已泄露的密钥时,会立即将其从 JWKS 中移除,GET /session/ 也会拒绝该密钥签发的所有 token。替换密钥会立即开始签名,无需提前一天发布。最多缓存 5 分钟的 JWKS 仍会接受已吊销的密钥,且尚不知道替换密钥,因此在缓存刷新之前,新 token 可能无法通过离线验证。

开始登录

打开托管页面,即 authorization_endpoint:
快速入门会为您构建此请求。

交换授权码

回调会接收 code 和 state。请校验 state,然后在 60 秒内交换授权码。每个授权码只能使用一次。请求体可以是 JSON,也可以是表单编码。
expires_in 表示访问 token 剩余的有效秒数。关闭多会话功能后,此次交换会结束该用户的其他会话。

访问令牌声明

访问令牌是一个 JWT,头部为 alg: ES256 和 typ: at+jwt。其有效期最多为 5 分钟,且绝不会超过所属会话的有效期。 ID 令牌的头部为 typ: JWT。它包含与访问令牌相同的声明,但不含 client_id,另外还包含 auth_time 和 email_verified,以及在有值时的 email、name 和 phone_number。只有授权码交换得到的 ID 令牌才会包含 nonce(前提是登录时带有该值)。请在该令牌中校验它,因为刷新得到的 ID 令牌从不包含它。ID 令牌永远不会被当作访问令牌接受。

在服务器上验证令牌

在信任任何声明之前,请检查以下所有项目:
  1. alg 为 ES256,typ 为 at+jwt。拒绝所有其他算法,包括 none。
  2. kid 存在于您应用的 JWKS 中,且签名验证通过。
  3. iss 等于您配置的签发者,aud 等于您的应用 ID。
  4. exp 和 iat 有效,允许最多 60 秒的时钟误差,且 sub、sid 和 jti 均存在。
  5. act 为 null。AI 智能体的访问令牌使用同一密钥签名,并带有相同的 typ、iss 和 aud;只有 act 能将其区分出来。除非该端点接受智能体,否则请拒绝它;若接受,则只允许 act.scopes 授予的操作。GET /session/ 始终拒绝智能体的令牌。
签发者应从您的配置中获取,切勿从令牌中获取。
离线验证无法识别刚刚结束的会话。在这点很重要的情况下,例如付款之前,请调用 GET /session/。

检查会话

响应包含 sub、sid、application_id、vendor_data、amr、mfa_verified、email、email_verified、phone、verified_identity、verified、expires_at、post_logout_redirect_uri 和 organizations。每个组织条目包含 organization_id、organization__name、role 和 custom_role。 此检查比离线验证更严格。以下情况也会导致检查失败:会话被撤销、空闲超时或超过有效期;用户被封禁,或其邮箱不再通过验证;会话不再符合您的 MFA 策略(例如用户添加了身份验证器应用,或成为组织管理员之后);或令牌已被刷新替换。失败时返回 401 {"detail": "invalid_token"} 以及 WWW-Authenticate: Bearer。 GET /session/ 每个 IP 地址每分钟允许 30 次请求,每小时允许 300 次,该限制与 DELETE /session/ 共享。请在每次请求时离线验证令牌,并将此调用保留给确实需要的时刻。每次成功调用都会计为活动,因此会重新开始会话的 idle_timeout。 已验证的电子邮件并不等于身份验证。请为此读取 verified:没有时其值为 null,而令牌中则为 {}。

刷新令牌

刷新会返回新的访问令牌、ID 令牌和刷新令牌,您所发送的刷新令牌随即失效。
  • 刷新令牌是一个随机字符串,有效期至会话结束。
  • 重复使用会结束会话。 当已使用过的刷新令牌再次出现时,Didit 会将其视为盗用的迹象:撤销该会话,并返回 400 {"error": "invalid_grant"}。该会话的令牌也会同时失效,包括之前那次刷新得到的令牌:使用其刷新令牌会失败,使用其访问令牌调用 GET /session/ 会立即失败,不过在过期之前(最多 5 分钟内)仍可离线验证。
  • 对于同一会话,请在标签页、设备和服务器实例之间一次只执行一次刷新,并将三个令牌一起替换。
  • 如果刷新以 400 失败或没有响应,请重新开始登录。不要盲目重试:如果刷新实际已成功,重试就构成重复使用。
  • 503 {"error": "temporarily_unavailable"} 表示刷新未发生,您的刷新令牌仍然有效。请使用退避策略重试。
  • Didit 会在刷新运行之前返回 429,因此请在 Retry-After 之后重试。令牌端点每个 IP 地址每分钟允许 30 次请求,每小时允许 300 次。此外,您应用的每个 POST 和 DELETE 请求共享机器人防护桶:这些端点合计每个 IP 地址每分钟 60 次请求,每台设备每分钟 30 次。在整个应用层面,刷新的桶容量为每分钟 6,000 次,其他所有 POST 和 DELETE 请求(包括浏览器和登录步骤)共用一个每分钟 3,000 次的桶,因此刷新不会耗尽您的登录额度。
  • 若访问令牌的有效期为 5 分钟,每小时 300 次刷新大约可满足 25 名保持活跃的用户。如果您的服务器要为来自同一地址的大量用户刷新,请仅在请求需要新令牌时才刷新,并尽可能在浏览器或应用中刷新。

退出登录

使用用户当前的访问 token 调用 DELETE /session/ 即可结束会话,并返回 204。该会话的刷新 token 随即失效,其访问 token 会立即无法通过 GET /session/ 验证;您离线验证的 token 则会保持有效,直到过期。之后,如果您设置了 post_logout_redirect_uri,请将用户跳转到该地址。 退出登录需要一个 GET /session/ 会接受的访问 token,即未过期、且未被刷新替换的 token。返回 401 表示会话并未结束。请先刷新,再使用新的访问 token 退出登录;如果刷新返回 400,则该会话已无法继续使用。 以下情况下,会话也会结束:
  • 超过 session_lifetime(默认 30 天)或 idle_timeout(默认 1 天),
  • 多会话功能关闭时,用户再次登录,
  • 开启 revoke_on_password_change 时,用户重置密码,
  • 您的团队在控制台中撤销该会话,或封禁该用户,
  • 已使用过的刷新 token 被再次发送。

有效期

按用途存储凭据

  • 验证 API 密钥和控制台 token 请保存在您的服务器上。
  • 浏览器端的访问 token 应尽量保存在内存中。对于服务端渲染的应用,请使用安全的 HttpOnly Cookie,并防范依赖 Cookie 认证的请求遭受 CSRF 攻击。
  • 移动端的刷新 token 请存储在平台提供保护的存储中。退出登录后,请清除本地状态。
  • 切勿将 token 放入 URL 或日志中。
继续阅读 JavaScript 快速入门、Next.js 快速入门 或 身份验证 API 参考。
最后修改于 2026年11月7日