Boloop 阅读示意图(AI 生成):沿浏览器、身份服务、回调、会话和访问权限检查登录。
迁移 Boloop 时,页面可以构建出来,后台登录却仍有独立的失败方式。一个很具体的例子是:代码里用于禁止跟随重定向的参数,在 Node 测试中被正常接受,放进实际使用的边缘运行时后,却直接抛出异常。
这类问题容易被一句“Google 登录失败”掩盖。接着就可能反复核对密钥、重新配置回调,甚至放宽身份校验。而这次真正需要改的,是一次请求的运行时兼容处理。
登录不是一个按钮而是一条往返路径
在 Boloop 的登录实现里,浏览器先向本站发起登录,再前往 Google;Google 将授权结果送回本站回调,服务端交换令牌、验证身份,然后创建本站会话。后续每一次管理操作,还要重新检查这个会话是否具有权限。
因此,看到 Google 的登录页,只能证明流程走到了其中一段。它不能证明回调地址正确、令牌能换回来,也不能证明回来的人就是有权管理网站的那个人。
迁移时,我会先把三处地址放在一起核对:浏览器实际访问的正式地址、服务端配置的站点地址、Google 客户端登记的回调地址。Google 要求回调地址与登记值精确匹配,协议、大小写和尾部斜杠都在匹配范围内。Google OpenID Connect 文档
构建时写入的地址与服务运行时读取的地址也要一致。只改前端环境变量,并不会自动更新服务端的运行配置。
一次被 Node 测试漏掉的运行时差异
当时的故障线索落在令牌交换阶段:应用给出服务商不可用的结果,却没有拿到 Google 的非成功响应状态。这使排查方向从“Google 返回了什么错误”,转到了“请求是否已经成功发出去”。
在当次使用的官方 workerd 运行时中,redirect: 'error' 会触发 Invalid redirect value。原来的 Node fetch 替身不仅接受这个选项,测试还断言它被传入了,所以绿色测试没有暴露真实环境中的不兼容。
修复改为 redirect: 'manual',并保留对非成功状态的拒绝。这里的目的仍然是不跟随服务商重定向:收到 3xx 就失败,而不是自动把敏感请求转发到另一个地址。
随后使用隔离的出站替身,在实际 workerd 中检查正常响应、整个 300–399 状态范围,以及超时失败。这个测试没有使用真实 Google 凭据;它解决的是运行时兼容性证明,真实 Google 登录仍需要在部署后单独走完。
认证成功后还要确认权限
Google 能证明账户身份,网站还要决定这个身份可以做什么。Boloop 将管理员身份绑定与普通登录分开,不让第一个登录的人自动成为管理员,也不把浏览器传来的身份头当作授权依据。
Google 的文档将 sub 定义为稳定的账户标识,并明确提醒不要用可能变化的邮箱作为用户主键。Boloop 的管理员检查同时核对预先绑定的账户标识与已验证邮箱;这是一项本站权限规则,不是所有网站都必须采用的通用方案。Google 身份声明说明
这部分验收要同时检查允许与拒绝:管理员能进入管理界面,普通已登录用户不能管理,匿名请求也不能读取私有数据。只看管理员自己的成功画面,会漏掉权限边界。
编辑到一半会话过期时会发生什么
迁移候选的一次隔离浏览器检查,使用的是虚构身份和测试记录。测试先打开编辑表单,输入未保存的标题,再让会话在另一个标签页过期。
保存返回 401 后,私有表单应被保护起来;重新建立同一个获授权身份、通过界面重新验证后,尚未保存的输入仍应保留,随后可以正常保存。这比“重新登录后能打开后台”多检查了一件实际会影响作者的事:身份恢复有没有把工作内容一起丢掉。
同一轮还检查了匿名入口、非管理员拒绝、退出登录,以及会话读取失败的界面恢复。由于测试中的 Google 提供方被禁用,这些结果不能充当真实授权弹窗与回调的验收结果。
迁移完成前我会走一遍的检查
先用正式入口发起一次完整登录,确认回调最终回到正确的后台。再刷新页面,检查会话是否仍然有效;退出后,再次访问管理数据应被拒绝。最后检查普通账户、会话过期、未保存编辑恢复,以及真正部署环境中的存储绑定。
记录证据时,只留下阶段、状态和可公开的错误分类。授权码、Cookie、令牌和完整回调查询串不应成为截图或文章素材。
Boloop 这段经历让我把迁移验收拆成三个结果:测试替身中的逻辑成立、目标运行时能执行、真实账户在正式站走通。三者分别回答不同的问题。一个页面成功上线之后,登录这条往返路径仍值得从头走一次。