跨域 SSO Token 传递的核心方案取决于域名关系:同根域名下设置 Cookie 的 Domain 属性为父域,不同根域名下采用 OAuth2 授权码模式或通过后端代理转发。必须注意现代浏览器要求跨域 Cookie 必须设置 SameSite=None 且强制开启 HTTPS。
先说结论:解决跨域 Cookie 限制需根据域名层级选择方案,同根域用父域 Cookie,不同根域用 OAuth2 或后端代理,且必须配置 HTTPS 和正确的 SameSite 属性。
- 适合:微服务架构、多子系统单点登录、第三方应用集成场景
- 先准备:确认域名层级关系、部署 HTTPS 证书、规划 Token 存储方式
- 验收:浏览器开发者工具 Network 面板确认 Cookie 携带状态及属性
快速处理思路
没有统一命令可解决架构级跨域问题,需按域名关系选择技术路线。同根域名场景直接配置 Cookie Domain 属性,不同根域名场景优先接入 OAuth2 协议,遗留系统可通过 Nginx 反向代理收敛域名。
为什么会这样
浏览器同源策略禁止不同源页面读取对方 Cookie,这是为了防止 CSRF 攻击和信息泄露。跨域 SSO 本质是在信任链建立的前提下,安全地共享会话标识,现代浏览器默认拦截跨站 Cookie 除非显式声明。
分步处理
步骤 1:确认域名关系
检查业务域名是否属于同一根域名,例如 app.example.com 和 sso.example.com 属于同根,app.com 和 sso.org 属于不同根。
步骤 2:同根域名配置
在设置 Cookie 时指定 Domain 为父域,例如 Domain=.example.com,同时设置 Path=/ 确保路径可达。
步骤 3:不同根域名配置
实施 OAuth2 授权码模式,用户认证成功后后端交换 Token,或通过 Nginx 将不同域名请求代理到同一源。
步骤 4:安全属性设置
跨域 Cookie 必须设置 SameSite=None; Secure,确保仅在 HTTPS 环境下传输,防止中间人攻击。
怎么验证是否生效
打开浏览器开发者工具,进入 Network 标签页,刷新页面后查看请求头中的 Cookie 字段是否包含预期 Token。点击具体请求查看 Response Headers 中 Set-Cookie 的 Domain、SameSite 和 Secure 属性是否符合配置。
常见坑
HTTPS 强制要求:Chrome 80+ 版本开始,SameSite=None 的 Cookie 必须标记 Secure,HTTP 环境下跨域 Cookie 会被直接拦截。
CSRF 风险:跨域 Cookie 容易遭受跨站请求伪造,需配合 CSRF Token 或双重提交 Cookie 机制进行防护。
Safari 智能防追踪:iOS Safari 的 ITP 机制可能限制跨站 Cookie 有效期,不同根域名场景建议避免依赖浏览器 Cookie 存储会话。
常见问题
LocalStorage 能代替 Cookie 解决跨域吗
不能,LocalStorage 同样受同源策略限制,不同域名无法直接读取对方存储的数据。
SameSite=Lax 能用于跨域 SSO 吗
不能,Lax 模式会阻止跨站请求携带 Cookie,仅适用于同站导航场景,跨域必须使用 None。
后端代理方案有什么缺点
增加了架构复杂度,所有跨域请求需经过代理层,可能成为性能瓶颈且需维护代理配置。
参考来源
- MDN Web Docs: Set-Cookie - https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Set-Cookie
- The OAuth 2.0 Authorization Framework - https://datatracker.ietf.org/doc/html/rfc6749
- Chrome Updates: SameSite Cookies Explained - https://developers.google.com/web/updates/2020/01/samesite-cookies