跨域名的 cookie 无法直接共享,但通过安全的单点登录(SSO)或 Token 机制,可以实现跨域登录。这背后既有浏览器同源策略的限制,也有业务上的权衡,下面把原理、方案和落地步骤掰开讲清楚。
跨域名 cookie 共享安全吗?先搞懂同源策略
很多人以为 cookie 就是个小文本,存哪都能用,浏览器对 cookie 的访问有严格的地盘意识,这就是同源策略,所谓同源,指的是协议、域名、端口三者完全一致,只要有一个不一样,cookie 就不认账。
同源策略是怎么管 cookie 的?
- 当你在
a.com登录,服务器返回的Set-Cookie会默认绑定在a.com这个域名下。 - 如果页面跳转到
b.com,浏览器不会把a.com的 cookie 带给b.com,因为b.com不是源。 - 反过来也一样,
b.com的 cookie 对a.com无效。
这不是缺陷,而是安全设计,如果没有同源策略,任意网站都能读取你的登录状态,那么你只要访问一个恶意网站,对方就能拿着你的身份去各大平台操作。跨域名 cookie 共享的本质,就是在不破坏这种安全边界的前提下,让两个不同域名的站点识别出同一个用户。
那为什么有时候感觉 cookie 能跨域?
你可能会遇到这种情况:访问 www.example.com 和 example.com,登录状态是通用的,这是因为两个域名属于同一个可注册域,通过设置 Domain=example.com 可以让子域共享 cookie,但注意,example.com 和 com 之间永远不行,不同顶级域之间更不行,这属于“同站点”共享,不是真正的跨域名。
真正的跨域名场景,shop.com 和 pay.com 要互通登录,靠 cookie 的 Domain 属性是做不到的,你需要一套专门的机制。
跨域登录实现方案:从 SSO 到 Token 实战
既然 cookie 不能直接跨,那就绕个路,核心思路是:让两个域名都信任同一个“身份来源”,目前业界主流有三种方案。
基于服务端 Session 的 SSO 单点登录
这是最经典的方案,你只需要一个认证中心,sso.com。
具体流程
- 用户访问
shop.com,发现未登录,重定向到sso.com/login。 - 用户输入账号密码,
sso.com验证成功后创建会话,同时生成一个授权票据(通常是 ticket)。 sso.com带着 ticket 重定向回shop.com的回调地址。shop.com拿着 ticket 再去sso.com换取登录状态,并在自己域名下种一个属于自己的 cookie。- 用户访问
pay.com时,重复上述过程,因为sso.com已经有会话,所以直接发 ticket,pay.com也种下自己的 cookie。
这个方案中,
shop.com 和 pay.com 的 cookie 始终是各自独立的,只是通过票据实现了“一次登录,处处可用”。安全性关键在于 ticket 的随机性和过期时间,以及回调地址不能暴露给第三方。
适用场景
- 企业内部多系统,OA、邮箱、ERP 统一登录。
- 域名数量不多(2-5 个),并且有足够的开发资源维护认证中心。
前端跨域共享用户态(不适合敏感数据)
有些人会想:我不搞重定向,直接在 shop.com 页面里写脚本,访问 pay.com 的接口,拿到 token 存到本地存储里,然后通过参数传给 pay.com,这能实现登录,但非常不安全。
- 本地存储容易受 XSS 攻击,脚本一注入,token 就跑了。
- 跨域请求本身受浏览器 CORS 策略限制,如果配置不当,等于给所有网站开放了接口。
行业共识认为:跨域登录时,尽量别用 localStorage 或 sessionStorage 传递身份凭证。 它适合存非敏感数据,比如用户偏好、主题设置,真正的登录态应该放在 httpOnly cookie 或内存中。
基于 Token/JWT 的无状态认证
这是现代前后端分离项目的主流做法,服务端签发一个 JWT(JSON Web Token),客户端保存它,每次请求带上,跨域时,两个域名只需要共享同一个“签发和验证”后端服务。
如何让两个域名都识别 JWT?
shop.com和pay.com共用同一个后端服务,那么后端签发 JWT 后,客户端把 token 放在请求头Authorization里即可。- cookie 不再是必需品,JWT 本身就是身份证明,它可以由任意域名接收并回传给后端。
- 但要注意,如果把 JWT 放在 cookie 里,你依然会遇到跨域问题,正确的做法是用 认证服务统一签发,两个前端通过重定向获取 token。
具体落地步骤
以 auth.com 作为认证服务为例:
shop.com前端检测到本地没有 token,跳转https://auth.com/authorize?redirect_uri=https://shop.com/callback。- 用户在
auth.com登录,服务端生成 JWT,将 JWT 作为参数拼在回调地址后,重定向回shop.com/callback?token=xxx。 shop.com前端收到 token,存放在内存中(不落盘),后续请求通过Authorization头带上。pay.com做同样操作,因为auth.com已经登录,所以直接带着新 token 跳回来。
这个方案中,cookie 在 shop.com 和 pay.com 上几乎不起作用,身份完全由 JWT 承担。它的安全性取决于 token 的签名强度和传输通道,一定要用 HTTPS,并且在 token 中加入过期时间和限定受众 aud。
适用场景
- 前后端分离、多端(Web、App、小程序)需要统一登录。
- 域名数量较多,且需要跨平台认证。
跨域登录时 cookie 和 token 该怎么选?
这是每个要落地的人都会纠结的问题,没有绝对的好坏,只看业务需求。
| 维度 | cookie 跨域 + SSO | Token/JWT 跨域 |
|---|---|---|
| 传输方式 | 浏览器自动携带 | 需要前端手动放在请求头 |
| 跨域难度 | 需要处理 CORS 和 SameSite | 只需后端验证签名 |
| 存储位置 | httpOnly cookie 更防 XSS | 容易受 XSS 攻击,需放内存 |
| 扩展性 | 适合同站点子域 | 适合完全不同的域名 |
| 常见案例 | 企业内网系统、子域共享 | 开放平台、移动端 + Web |
如果你要对接的是完全不同的域名,我建议你优先考虑 JWT 方案,因为 cookie 的 SameSite 属性在跨域场景下会带来额外的坑。
SameSite 属性是跨域 cookie 的隐形门槛
SameSite 有三个值:
Strict:严格限制,跨域请求完全不携带 cookie,最安全但体验差。Lax:大多数跨域请求不携带,但顶级导航(比如点击链接跳转)会携带。None:允许跨域携带,但必须同时设置Secure,也就是要求 HTTPS。
业内专家指出,很多跨域登录“莫名其妙掉线”的问题,都是因为 SameSite 没设置为 None。 但注意,SameSite=None 意味着浏览器会在跨域请求中带上你的 cookie,这需要配合 Access-Control-Allow-Credentials: true,并且服务器要明确指定允许的源,不能使用 。
设置示例
Set-Cookie: session_id=abc123; SameSite=None; Secure; HttpOnly
SameSite 设置错了,即使你做了 SSO 跳转,cookie 也不会跟着请求到达后端,登录自然失败。
跨域名 cookie 安全共享的最佳实践
前面讲了方案,下面说安全细节,毕竟登录凭证是关键资产,一旦泄漏,整个系统就裸奔了。
永远使用 HTTPS
跨域场景下,域名间的重定向、回调、token 传递都要经过网络,如果走 HTTP,中间人可以直接截获 ticket 或 token,冒充用户登录。这是底线,没有商量的余地。
给票据和 token 设置极短的有效期
- 授权票据 ticket 有效期控制在 5 分钟内。
- JWT 的 access token 有效期建议 15 分钟到 2 小时。
- 刷新令牌(refresh token)可以长一些,但必须存放在 httpOnly cookie 里,且只发送给认证服务。
校验回调地址和来源
在 SSO 跳转时,认证中心必须维护一个合法回调地址白名单,如果回调地址可以自定义,攻击者就能构造一个链接,把合法用户的 ticket 发送到自己的服务器。
具体做法是:认证中心在跳转前校验 redirect_uri 参数,只允许预先注册的域名,在换取 token 的阶段,接口要校验
state 参数,防止跨站请求伪造。
隔离关键操作与普通请求
即使实现了跨域登录,也不能让所有操作都继承同一份信任,涉及支付、修改密码、删除账号等高风险操作,应该要求再次输入密码或进行二次验证,这样即使别人拿到了你的会话 cookie,也无法轻易完成关键操作。
日志监控与异常感知
记录每个跨域登录的 IP、设备、时间戳,如果同一个账号在短时间内从不同地区登录,应该触发告警并临时冻结会话,这不是让你搭一套复杂的风控,最简单的做法是在认证中心保存最近一次登录的 IP,对比发现变化时要求重新验证。
Q&A 模块
跨域名 cookie 共享是不是可以用 iframe 实现?
可以,但不推荐,你可以把认证页面嵌在 iframe 里,通过 postMessage 向父页面传递登录凭证,但 iframe 方案会遇到 X-Frame-Options 和 SameSite 的限制,而且浏览器第三方 cookie 拦截政策越来越严格,很多现代浏览器默认阻止 iframe 中的第三方 cookie,所以这种方式正在被淘汰,更适合的应用场景是嵌入第三方服务,比如地图、聊天窗口,而不是核心登录。
跨域登录时,CSRF 攻击怎么防范?
跨域登录过程中,最危险的就是 CSRF(跨站请求伪造),比如攻击者诱导用户访问 evil.com,然后向 pay.com 发起一个修改密码的请求,因为浏览器自动带上了 pay.com 的 cookie,所以请求是合法的,防范措施有三层:第一,把 cookie 的 SameSite 设为 Lax 或 Strict;第二,在表单或请求头中加入 CSRF token,服务端校验;第三,对关键操作改用 POST 方法并且验证 Content-Type 必须为 application/json,对于 SSO 回调接口,必须校验 state 参数与发起登录时生成的随机数一致。
跨域登录后,如何确保退出登录的同步性?
在 SSO 方案中,退出通常由认证中心统一处理,用户访问 shop.com/logout 时,重定向到 sso.com/logout,认证中心清除全局会话,然后通过前端路由或重定向通知所有已登录的子域(pay.com)清除各自的本地 cookie,如果是 JWT 方案,更简单的做法是让认证中心维护一个“已注销 token 黑名单”,所有服务端在验证 token 时检查该黑名单,注意,因为 JWT 本身是无状态的,你没有能力强制让它失效,所以要么把有效时间设得很短,要么用可靠的黑名单机制。
跨域登录的核心从来不是“让 cookie 穿透域名”,而是让多个域名共同信任一个身份源,无论是 SSO 票据还是 JWT,本质都是在浏览器同源策略的约束下,用安全协议架起一座桥,挑一个与业务规模匹配的方案,把 HTTPS、过期时间、回调校验这几道门槛装好,剩下的就是按部就班地迭代了。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/613054.html





