SSO单点登录重定向解决方案
当我们写好SSO单点登录服务的代码后,通过调用接口方式验证,流程看似正常,但开始与前端联调就出现问题了。
流程是这样的:前端在首页使用ajax访问后端获取菜单或者用户信息的接口,以触发登录校验,如果未登录则重定向到SSO登录页面。
但这一步就出问题了,原因是ajax无法拦截302处理。当ajax接收到302响应时,看起来就像是ajax直接向重定向链接发起请求,而不是让浏览器重定向,结果啥事也没干。
关于ajax无法拦截302处理的原因,笔者从网上找到的解释如下。
服务器将302响应发给浏览器时,浏览器并不是直接进行ajax回调处理,而是先执行302重定向,从响应头中读取Location信息,然后向Location中的Url发出请求,在收到这个请求的响应后才会进行ajax回调处理。
大致流程:ajax -> browser -> server -> 302 -> browser(redirect) -> server -> browser -> ajax callback。
原本是为了让前端以最少的改动接入SSO,但因为笔者对前端的了解较浅,才犯了这样的错误。
既然ajax无法处理302,那也只能修改流程,让前端主动发起重定向了。
流程修改后,当后端验证用户未登录或登录过期时响应401状态码,同时body给出重定向链接,而前端需要全局拦截401错误,从响应body获取链接并让浏览器重定向到指定链接,该链接就是由后端拼接好的跳转到SSO登录的链接。
最后还有一个cookie问题。由于本地测试,前端将请求转发给部署到测试环境的后端,前端的域名为127.0.0.1,后端测试环境域名为xxx. com,导致本地测试跳转到SSO登录成功并返回后,前端向后端发起请求依然响应401。
原因在上篇已经描述过了,就是因为域名不同,前端使用ajax发起请求,浏览器并不会将xxx.com域名下的cookie带上,只会带上127.0.0.1域名下的cookie。
解决该问题只需要修改传给SSO登录成功后重定向的checkToken接口的域名为前端本地测试的域名,由前端将请求转发给后端,或者在nginx配置将此接口的请求转发给后端处理,只有这样session才能保持一致。
除此之外,跨协议无法重订向。也就是说,sso部署在测试环境域名为https://sso.xx.com,而接入sso的服务在本地测试域名为http://127.0.0.1,想要从https://sso.xx.com登录成功后重定向回http://127.0.0.1是不支持的,原因是跨协议重定向了,由https协议变成了http协议。
从这些事情可以看出,实战很重要!即便理解了流程、实现原理,但不动手实战就学不到细节,无法从各种踩坑过程中成长。
本文转载自微信公众号「Java艺术」,可以通过以下二维码关注。转载本文请联系Java艺术公众号。
相关文章
- 在 Asp.Net Core 中什么是认证和授权
- WPF中用户控件和自定义控件
- WPF常用UI库和图表库(MahApps、HandyControl、LiveCharts)
- WPF 日期选择器和时间选择器
- WPF-带填充的 WrapPanel
- .Net 7 团队把国内的龙芯确实当做一等公民和弃用的项目
- Android WebView不能加载ajax?加载ajax无效?
- asp.net之treeview无法显示树结点图标(IP与域名的表现竟不一样)
- STM32F401的外部中断EXTI
- 通过ionice和nice降低shell脚本运行的优先级
- SpringMVC的Ajax提交
- CLion + MinGW64配置C语言开发环境 Visual Studio安装
- 2023 年 dotnet 仓库社区年度调查已经开始
- 单片机IO直接驱动继电器,你想多了
- 为什么大家都用三极管来配合单片机IO口驱动负载
- Ajax文件上传时:Formdata、File、Blob的关系
- 记录一些在此之前不知道的Web API
- django csrf 验证问题及 csrf 原理
- Microsoft Visual Studio 开发 fiddler 插件过程总结
- 为啥国人偏爱 Mybatis,而老外喜欢 Hibernate/JPA 呢?