Caddy forward_auth 登录循环:Cookie 是否只属于认证域名
认证和应用拆成兄弟域名后登录循环时,核对浏览器的Cookie范围与真实请求。同公开主机路径布局需同步回调契约,父域SSO不能默认扩大。
登录页面已经显示成功,回到受保护页面却又跳转登录。本机把认证和应用放在 localhost 时正常,上线拆成两个域名后才出现循环,可以先检查浏览器是否把认证 Cookie 发给了应用域名。
例如认证页面在 auth.example.com,应用在 app.example.com。如果登录响应设置了没有 Domain 属性的 Cookie,它只属于前一个主机,浏览器不会向后一个主机发送。Caddy 无法从应用请求中转发浏览器没有发送的 Cookie。本文限定这一主机范围问题;会话失效、回调错误和 Path 不匹配也会造成登录循环,不能仅凭现象断定根因。
以浏览器的真实请求为准
在测试账户中保留登录到受保护页面的完整请求链。查看登录响应的 Set-Cookie、浏览器存储中的域名与属性,以及随后向应用发送的请求有没有对应 Cookie。下面是主机范围不匹配的示例,值已遮盖:
登录响应地址:https://auth.example.com/login
Set-Cookie: session=REDACTED; Path=/; Secure; HttpOnly
下一次请求:https://app.example.com/account
没有 Domain 的 Cookie 是 host-only Cookie,Path=/ 也不会扩大它的主机范围。即便两个站点共享父域、都用了 HTTPS,这个限制仍然存在。显式指定认证主机自身为 Domain 可以覆盖其子域,但不会让 Cookie 自动去往兄弟域名。
检查浏览器给出的拒绝或未发送原因。Caddy 日志里的 Cookie: [] 可能只是敏感头被隐藏,不能直接当作网络请求没有 Cookie 的证明。确需查看内部请求时,使用受控诊断、遮盖值并限制保存范围,不为日常访问长期记录凭据。
如果浏览器已经向应用发送了正确 Cookie,再核对应用到认证服务的请求。forward_auth 通常会随代理规则传递原请求头;header_up Set-Cookie 设置的是上游请求头,方向不对。也不要用含糊的通配 Cookie 占位值覆盖一个本来完整的 Cookie 请求头。
同一公开主机下安排认证和应用
若认证产品支持,把认证入口与应用安排到同一个公开主机、用不同路径区分,是避免兄弟域名会话范围问题的一条方案。需要同步核对认证产品的外部地址、登录链接、回调、跳转白名单及 Cookie Path,不能只在代理里改转发地址。
比如公开登录入口为 https://app.example.com/auth/,受保护页面为同主机的 /account。Cookie 即使属于这个主机,若 Path 仍限定 /auth/,也不会发往 /account;应由应用或认证服务按会话契约生成正确路径。Caddy 内部把请求转给另一台服务,不会改变浏览器基于公开 URL 的判断。
合入既有路由时保留登录与回调端点的适当开放,以及业务路径的鉴权,不要让认证入口反复鉴权自己,也不要为了结束循环放开整个应用。已有 Path 问题可对照本站的 Cookie 路径排查,但不要把路径改写当作主机范围修复。
父域 Cookie 需要单独确认信任范围
认证系统有经过批准的跨子域 SSO 设计时,可能明确采用父域 Cookie。扩大到 Domain=example.com 会把它的发送范围扩展到相关子域,须核对这些子域的控制权与信任关系,不能作为遇到循环时的默认改法。
认证主机不能直接把 Cookie 的 Domain 写成兄弟应用主机;浏览器会拒绝不匹配的设置。带 __Host- 前缀的 Cookie 要求 Secure、Path=/ 且没有 Domain,不能一边保留这个名字,一边加入父域 Domain。SameSite=None 也不会解除 Domain 限制,跨站策略和主机范围要分别检查。
验收包含退出和旧 Cookie
保存原配置及认证产品的相关外部地址设置,先在本机检查路由与配置,再按原部署流程修改。用新的测试会话确认登录、应用访问、刷新和退出均走预期路径,浏览器确实在应用请求中发送会话 Cookie,受保护页面不再循环。
服务器设置改变后,浏览器里的旧域名或旧 Path Cookie 仍可能存在。只清理测试账户在相关站点的必要 Cookie 后重试,避免同名不同范围的旧值干扰判断。若回退,同步恢复代理、认证公开地址和回调设置,并再次检查浏览器请求;不能只以主页能打开作为会话恢复的证据。


