这是 20 年 7 月左右的事了,当时解决了这个问题就想将它记录下来,但是那段时间实在是太忙了。
首先单点登录并不算什么很复杂的事,按常规的架构来说其实大部分是后端在进行交互,前端只需要进行一个参数的传递,这里画一个简单的单点登录流程图。
为什么说这是一次非常规单点登录呢,因为接入的业务系统没有到鉴权服务器上进行鉴权,而是将鉴权动作放到了前端实现。本来应该是业务服务器通过授权码进行鉴权的动作变成了前端使用鉴权服务器 token 获取业务服务器 token,然后业务服务器直接使用。正常来说我们将业务服务器的 token 放到地址栏,业务服务器也是可以正常使用的。由于 token 直接显示到地址栏,一个是不优雅(谁知道 token 有多长呢),另一个是不安全。
要求以往接入的业务系统改造那肯定不现实,那就只能将鉴权服务器返回的 token 缓存到 cookie 或者 localstorage。但是这里有一个问题,如果要将数据缓存到 localstorage,那就要遵循同源策略;如果将数据缓存到 cookie,那就要求域名或者主机相同。很遗憾的是这么多业务系统肯定达不到这样的要求,难道就止步于此了吗,肯定不会的。
刚好 postMessage 可以实现跨域通讯,于是就有了下面的架构图。
虽然一定程度上解决了优雅和安全的问题,但是也存在其他的问题,比如:Token 失效,原因在于在点击子系统时,子系统内的 iframe 并未完成加载,导致后续流程不能正常进行。对此,我们可以在子 Iframe 加载完成之后向网关返送 ready 通知,在 ready 之前都处于 loading 状态,时长取决于所有系统加载时长最大值(毕竟不知道用户会点击哪一个系统)。
[越努力,越幸运!]