前言
企业里也许会拥有多个一级域名,为了让用户使用体验更好,无需在每个站点都登录一遍,故产生了单点登录的需求。一个站点登录,其他站点同步登录状态,站点间跳转更加流畅。
大纲
- 互联网中的登录
- session 与 cookie
- 单点登录
互联网中的登录
什么是登录?
登录即客户端服务器间确定当前用户的实现方式。
目前互联网实现登录的方式大多是手机号、社交账号登录等。对于 C/S 架构的网站,不直接采用设备id登录,主要有这些方面的原因:
- 设备id不可靠,容易伪造
- 一个设备有登录多个账号的需求
主要还是来源于安全可靠。不依赖硬件,转而依赖上游运营商或三方社交网站。
ps: 现在几乎所有互联网产品都需要绑定手机号,目的是为了合规和便于用户运营。
session 与 cookie
session 是保存在服务端内存中的用户数据。cookie 是保存在客户端,为无状态的 http 增加状态的一种方式。
cookie 中保存 sessionid ,服务端保存 sessionid 与 session 的关系,一个请求过来,可根据 sessionid 查询出会话数据,进而实现业务逻辑。
互联网多使用微服务架构,拿电商举例,例如用户服务、订单服务、商品服务。每个服务都保存一份 session 数据,会涉及到状态更新问题,所以大多是所有服务都从用户服务中获取会话数据。
但是依然存在问题:
- 用户服务自己也有多台服务器,还是会有状态管理问题
- 服务器的内存占用,在用户量大的场景下会比较明显
- 其他服务都需要向用户服务请求获取数据,压力很大
无状态登录
jwt(JSON Wen Token),以json格式的数据将用户状态保存在客户端。一般会包括用户id以及一些必要数据,因为大多数场景下,要使用到用户id的信息。这些信息在登陆时将用户信息加密,然后set到cookie里面。每次请求时会携带jwt,各个服务,只需要通过解密算法,获取到用户基本信息即可,无需向用户服务发起请求。
单点登录
单点登录是 web 场景下,跨域名登录态统一的实现方式。
cookie 只能写入到当前域名及其父域名。那么多个二级域名(a.com, b.com),如何同步登录态呢?
方式一:登陆时同步
把多个二级域名归类下,分为主域名和次域名。主域名只有一个,次域名多个。
在当前域名登录成功后,生成有时效性的 token ,再批量调用下其他域名的登录态同步接口,并携带此 token,此时就同步成功了。当然使用 ajax 调用的话会跨域,可以做下 CORS(跨域资源共享) 或使用 jsonp 调用。
优点:
- 登陆时同步,频率低,服务压力小
- 实现平滑,只影响登录功能,对整个网站架构无影响
缺点:
- 浏览器隐身模式功能无法使用,需要从产品层面考虑是否能接受
- 子域名较多时,会影响当前站点登录体验(速度会比较慢)
方式二:使用时同步
在 a.com 登录成功后,不立即同步到 b.com 站点。
用户在使用 b.com 时调用 a.com 获取 code ,服务端消费 code,登录成功。
此方式需要在所有 b.com 站点的页面上进行登录检查。
优点:
- 不影响主站逻辑
- 使用时才登录
缺点:
- 由于需要在所有页面进入时检查,所以对于现有页面架构有一些调整
- 还是由于上面一点,检查到需要更新用户信息时,刷新页面或无刷新内部更新用户状态(对于大型网站来说,这会比较困难,模块比较多且可能并没有规范获取用户信息的功能)
- 隐身模式无法使用
方式三:前端维护 Token
即登录态保存在前端缓存区,上面 2 种方式都是继续 http-only cookie 的,且相对比较安全。
前端维护 Token 即所有 api 请求,需要网站自行处理 Token 携带问题,不像 cookie 浏览器帮你做了。这种跨站同步登录态的方式即主站登录后,保存 token 到缓存;进入子站后,通过 iframe 内嵌主站页面,postMessage 获取主站 Token,甚至可以不拷贝到子站,每次都从主站获取。
这是 Google 与其子站(Youtobe)的实现方式。
优点:
- 隐身模式可以使用
- 前端维护 token 比较灵活,甚至可以同一浏览器不同 Tab 同时使用多账号
缺点:
- 安全问题,很容易被三方脚本(例如三方 npm 包、统计脚本、XSS 注入)攻击。除非你不用三方的脚本或三方脚本对你都是白盒,以及所有用户输入与页面 url params 都做好了 XSS 防御工作,不然所有使用站点的用户登录态都将暴露。
- 对网站架构影响比较大(如果一开始使用 cookie 的话)
方式四:统一的passport
登录都在统一入口,且所有未登录站点都重定向到此入口进行登录或同步登录状态。入口登录后需要生成一次性消费 Token ,携带给子站消费 token 页面,子站登录成功后,再重定向到用户想要访问的页面。
优点:
- 简单粗暴,所有登录都通过统一入口与重定向来做
- 隐身模式可用
缺点:
- 体验不太好,会有页面跳转的过程
总结
通过本篇文章,我们了解到互联网登录是如何实现的,Session 与 Cookie 的作用。最终引入我们的主题,单点登录实现的几种方式,以及他们各自的优缺点。
可以看到每种实现方式都有利弊,我们需要综合分析当前业务场景,确定实现方式。实现方式本身没有优劣之分,不看场景讨论解决方案,都是空谈。针对场景做一些可接受的取舍,并符合未来场景发展趋势,即是架构之道!
以上。