身份与回调
登录回来之后,先确认是哪一次登录
一个浏览器可以同时打开多个登录窗口,也可能在回调途中换成另一段会话。Account 用原始意图、浏览器绑定和一次性证明保留关联;业务应用再建立自己的会话。
登录从一个有边界的原始意图开始
业务后端发起登录时,保留发行者、客户端、精确回调地址、state、nonce 和 PKCE 证明。浏览器收到的选择标识只用于找到原记录,不能单凭这个标识取得账户身份或 CSRF 权限。Account 负责身份认证,应用自己的登录事务和最终会话仍由应用后端持有。
回调处理应重新核对这个绑定,再解释收到的是授权码、已确认的拒绝还是无法确认的结果。登录成功页或 URL 中的文字没有签发会话的能力。设计把回调、令牌核验和业务会话提交分别定义,避免一次导航承担过多含义。
两个窗口共享浏览器,不共享登录结果
设想同一浏览器先后为应用 A 和应用 B 打开登录。它们可以共享浏览器绑定 Cookie,却必须拥有不同的意图记录、客户端、返回地址和 state。A 的回调只能完成 A;刷新一个已消费、已过期或绑定错误的选择标识,也不能自动改用 B 的上下文。
两次成功登录可以分别建立自己的 Account 会话。浏览器最后保留哪个 Cookie,遵循实际收到响应的顺序;这不等于另一会话已被撤销。退出也必须针对原来的会话,避免迟到的操作结束刚刚建立的新登录。Yaoledge 在产品侧通过原会话标识核对退出目标。
| 对象 | 承担的作用 | 不授予 |
|---|---|---|
| 登录选择标识 | 定位特定原始意图 | 账户身份或新的登录机会 |
| 浏览器绑定 | 关联发起该意图的浏览器 | 单独证明用户已认证 |
| 已认证会话 | 在自身期限与限制下使用账户 | 替另一个原始意图消费证明 |
先取得消费权,再进行一次外部交换
外部身份提供方的回调先校验固定路由、参数、原 state、浏览器或添加凭据的原会话,以及期限。重复参数、混合的 code 与 error、错误提供方和失配的浏览器绑定,在联系提供方之前就被拒绝。
对于携带授权码的流程,Account 先在短事务中消费活动记录。只有确认取得这次消费权的调用可以交换授权码并读取身份;提交结果未知时不发送。外部交换之后,最终写入再次核对原意图、限制、期限和身份归属,存储重试复用已经取得的证据,不再发送第二次交换。
校验原绑定
解析一次回调参数,核对原浏览器或原添加凭据会话。
消费活动流程
确认消费事务完成后,才进行本次提供方交换。
提交身份结果
重新核对原上下文,用同一份已验证证据完成写入。
身份令牌与访问权限各有接收方
业务应用通过 SDK 校验完整登录响应,包括签名、发行者、客户端受众、原 nonce、有效时间和账户标识。只有完成核验后才取得 VerifiedLogin。应用据此提交自己的新会话;一个跳转上的 login_result 标记只用于反馈,不代替当前会话查询。
同一身份系统还可能发放不同用途的访问凭据。OIDC 身份令牌、UserInfo 访问令牌与 Transact 机器授权具有不同的受众和权限;不能因为它们来自同一发行者就互相替代。用途由原注册和实际接收方共同约束。
| 凭据 | 指定用途 | 接收方检查 |
|---|---|---|
| OIDC ID Token | 向原业务客户端提供已验证身份 | 发行者、受众、nonce 与期限 |
| UserInfo 访问令牌 | 读取原账户的 UserInfo | 资源、账户、客户端与期限 |
| Transact 机器授权 | 执行已登记的交易 API 权限 | 资源受众、客户端与确切 scope |
无法确认时,重新开始应是一个明确动作
如果外部交换已经发出、回复却丢失,重访旧回调不能再交换一次。若最终会话写入无法确认,页面应说明未知,并引导从原业务应用明确发起新登录。新意图保留新的证明,旧流程不会自动转移到它上面。
添加外部凭据还有不同的恢复路径:可以在当前权限下核对原账户已有绑定。读回必须限定原账户,不能因为浏览器途中换了会话,就把另一个账户的状态当作原操作结果。添加凭据本身也不会创建一个新的账户或替换登录会话。
已建立原绑定时再解释结果
核对来源、账户和原意图后,才判断可继续的动作。
旧回调不提供自动重试许可
已消费或未知的外部交换,不因刷新页面而重新发送。
验证关联,而不只验证登录按钮
设计要求用互不相同的客户端、账户和回调时序构造独立预期。这样才能暴露跨窗口串线、重复外部交换和迟到退出等问题。下面列出应核对的结果,不表示这些实验已在某个部署环境完成。
| 情形 | 核对什么 | 保留的边界 |
|---|---|---|
| 两次登录交错完成 | 各自的客户端、回调与 state | 不采用另一个意图 |
| 两个回调争用同一原 state | 实际提供方交换次数 | 仅确认消费的调用发送 |
| 消费后丢失外部回复 | 旧回调不产生新交换 | 未知不改写成失败或成功 |
| 退出前换成新会话 | 原会话标识与当前 Cookie | 不撤销替换后的会话 |