当前位置: 首页 > 科技观察

SSO单点登录重定向解决方案

时间:2023-03-11 23:11:32 科技观察

我们在写完SSO单点登录服务的代码后,通过调用接口验证,流程貌似正常,但是在开始和前端联调的时候就出现了问题.流程如下:前端在首页使用ajax访问后端接口获取菜单或用户信息触发登录验证,未登录则重定向到SSO登录页面。但是有一个这一步有问题,因为ajax不能拦截302处理。当ajax收到302响应时,看起来ajax直接向重定向链接发出了请求,而不是让浏览器重定向,但什么也没有发生。关于ajax无法拦截302处理的原因,我在网上找到的解释如下。当服务器向浏览器发送302响应时,浏览器并不直接进行ajax回调处理,而是先进行302重定向,从响应头中读取Location信息,然后向Location中的Url发送请求。ajax回调将在请求响应后处理。一般流程:ajax->浏览器->服务器->302->浏览器(重定向)->服务器->浏览器->ajax回调。本来是想用最少的改动让前端连接到SSO,但是因为作者对前端的了解比较浅,所以犯了这样的错误。由于ajax无法处理302,只能修改流程,让前端主动发起重定向。流程修改后,当后端验证用户未登录或登录过期时,响应401状态码,同时body给出重定向链接,前端需要拦截全局401错误,从响应体中获取链接让浏览器重定向到指定链接,该链接是后台拼接的跳转到SSO登录的链接。最后还有一个cookie问题。由于是本地测试,前端将请求转发给部署在测试环境中的后端。前端域名为127.0.0.1,后端测试环境域名为xxx.com。本地测试跳转到SSO登录成功返回后,前端发送给后端发起的请求仍然返回401,原因在上一篇已经讲过了,因为域名不一样,前端使用ajax发起请求,浏览器不会带xxx.com域名下的cookie,只会带127.0.0.1域名下的cookie。解决这个问题,只需要修改SSO登录成功后重定向的checkToken接口的域名为前端本地测试的域名,前端会将请求转发给后端,或者配置nginx将该接口的请求转发给后端处理。只有这样,会话才能保持一致。除此之外,跨协议重定向是不可能的。即测试环境下sso部署的域名为https://sso.xx.com,连接sso的服务本地测试域名为http://127.0.0.1。如果想从https://sso.xx访问.com登录成功后不支持重定向回http://127.0.0.1,因为跨协议重定向从https协议变成了http协议。从这些事情就可以看出,实战很重要!即便了解了流程和实现原理,但不动手实战就学不会细节,也无法从各种坑中成长。本文转载自微信公众号“爪哇艺术”,可通过以下二维码关注。转载本文请联系爪哇艺术公众号。