登录状态跨域共享实现方案
背景介绍
企业服务由于合规问题需要独立域名,脱离主域名,从而导致无法使用主域名登录状态,需要重新设计开发一套独立的登录功能。
观察企查查相关业务发现,对方也有类似的业务场景,例如客找找,经过测试发现客找找能够共享企查查的登录状态并且能够实时同步。
技术调研
一般情况下 cookie 跨域指的是子域名和主域名之间共享 cookie,即 a.baidu.com,b.baidu.com 共享 www.baidu.com 下的 cookie。只需要设置域名 domain 为”.baidu.com”即可。
但如果是 www.a.com 和 www.b.com 就无法实现 cookie 跨域,无论是浏览器端还是服务器端都无法获取到对方的 cookie。
QCC 实现方式调研
首先观察 qcc 的 sessionid 是如何存储在 cookie 中的:

发现其并没有设置 HttpOnly 和 Secure 这两个字段,而这两者在保证 cookie 安全中是非常重要的,一般肯定会设置,除非是有特别的考虑。
考虑到这两个属性的特点,怀疑是要实现跨域共享就必须在前端代码中读取这个 cookie。我们在浏览器调试工具栏中查看登录流程调用的请求发现:

当用户在 qcc.com 中登录成功后,前端会调用 kezhaozhao 的接口,将 sessionid 通过 url 参数传到 kezhaozhao 后台,此接口为跨域接口。
客找找后台接受到 url 参数中的 id 后,再将 sessionid 写入到 cookie 中,由于此接口在 kezhaozhao 域名下,服务端可直接写入。之后用户继续访问 kezhaozhao.com 就能够自动携带 qcc 的登录信息。
流程图

一些细节
关于登录状态同步
由于 a.com 和 b.com 使用的同一个 sessionid 标识用户状态,当用户在任意站点登出时,只需要在服务端将此 sessionid 失效即可同时让另一站点登录状态失效。
关于登录逻辑
上面的流程图是以 a 后台为主项目实现的,登录逻辑在 a 后台中实现,之后同步给 b 后台,用户无法直接在 b.com 站点登录。
也就是说,当用户在 b 触发登录后,会先跳转到 a 的登录页中,登录完成后再重定向回来,在 b 也就无法做弹窗登录之类的交互。
如果需要在 b.com 实现弹窗交互,也就是直接在 b.com 登录,在上面流程图的基础上,需要将 a 后台和 b 后台的逻辑“镜像”拷贝一份,这样才能实现双向的登录状态同步。
限制条件
首先负责登录逻辑的站点,无法设置 cookie 为 httponly,否则 js 无法读取到 cookie 内容,这会丧失掉一部分的安全性。
当需要同步的站点比较多时,逻辑会变得非常复杂,所有站点各自登录后都需要通知其他站点,登录状态变得难以管理。