网络基础 登录对接CAS-跨域导致的一个意想不到的Bug
登录对接CAS-跨域导致的一个意想不到的Bug
背景描述
业务需求是平台登录,接入Cas验证
问题描述
- 平台登录页,点击登录方式,跳转Cas登录页,提交登录请求,结果发现,又返回平台登录页;
- 再次点击登录方式,登录成功,跳转到目标页面。
问题排查
排查方向-浏览器兼容性问题
这个问题,开发人员在其本地开发环境复现不了,仅在我本机可以,因此,他们初步怀疑,这个是浏览器兼容性问题。开发人员经过一段时间排查,终究没找出问题所在。
排查方向-跨域问题
笔者无意中发现,登录成功后,再次退出登录,然后重复该动作,这种情况下是,问题是不可复现的,但通过点击流量收藏夹中的网址,实现登录时,问题就重现了。
于是,仔细检查了下收藏的网址,发现是网址使用的是http协议,非https,然后我很开心的告诉开发,这种情况下能复现。
经过一番分析后,开发人员得出了结论,就是跨域问题,导致前端获取不到存储到localStorage中的Token(最终会存储为Cookie),所以访问后端时,没有携带该token值,最终登录失败,并基于此准备一些相对复杂的解决方案。
根因分析与解决方案
根因分析
结合自己的分析,及开发的解释,依旧是云里雾里,感觉开发没有说清楚里面的逻辑,终不能说服自己,于是结合请求过程,同开发进行二次探讨。
以下是整个操作过程中,笔者抓取的一些关键请求信息
- 访问前台页面
GET http://target.sit.example.com/
自动触发登录检测请求
GET http://target.sit.example.com/api/admin/checkLogin
关键响应头及响应体
Set-Cookie: _TOKEN_KEY_=; Path=/; Expires=Thu, 01-Jan-1970 00:00:00 GMT; Max-Age=0 {"msg":"to login","result":{"redirect":"https://wcas.sit.example.com/cas/login?service=https%3A%2F%2Fmg.sit.example.com%2Fapi%2Fadmin%2Flogin%3FloginType%3DCAS-DATA"},"succ":"jump"}
检测结果为未登录,程序根据目标平台提示,跳转Cas登录页
GET https://wcas.sit.example.com/cas/login?service=https%3A%2F%2Fmg.sit.example.com%2Fapi%2Fadmin%2Flogin%3FloginType%3DCAS-DATA
提交Cas登录
POST https://wcas.sit.example.com/cas/login?service=https://mg.sit.example.com/api/admin/login?loginType=CAS-DATA
关键响应头:
Location: https://mg.sit.example.com/api/admin/login?loginType=CAS-DATA&ticket=ST-43509-fE0FeJmFdA3TlLW9dV9Y-casnode1&language=zh&country=CN&variant=CN
Set-Cookie: CASTGC-D-SS="";Version=1;Path=/cas;Domain=.sit.example.com;Expires=Thu, 01-Jan-1970 00:00:00 GMT;Max-Age=0
Set-Cookie: CASTGC-D=TGT-939448-9ZhaREwusKuYIvucwdASdPOoCx6yIwpopNWdhS4M2Ousq2Opsu-O2QFU3-casnode1;Path=/cas;Domain=.sit.example.com
Set-Cookie: CASTGC-D-SS=TGT-939448-9ZhaREwusKuYIvucwdASdPOoCx6yIwpopNWdhS4M2Ousq2Opsu-O2QFU3-casnode1;Path=/cas;Domain=.sit.example.com;HttpOnly;Secure;SameSite=None
根据服务器返回302响应状态码及location请求头,自动重定向
GET https://mg.sit.example.com/api/admin/login?loginType=CAS-DATA&ticket=ST-43509-fE0FeJmFdA3TlLW9dV9Y-casnode1&language=zh&country=CN&variant=CN
关键响应头
Location: https://target.sit.example.com/#/home?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMTM2NzU5OSIsImV4cCI6MTY4MDI2NzE0M30.auqOB37uknCdoleGdEyCjpUoPlrEtsoV4z1p4zWmpsI&loginType=CAS-DATA
Set-Cookie: JSESSIONID=node0vltj8s5ysap840ozd62zcyau14488.node0; Path=/
Set-Cookie: _TOKEN_KEY_=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMTM2NzU5OSIsImV4cCI6MTY4MDI2NzE0M30.auqOB37uknCdoleGdEyCjpUoPlrEtsoV4z1p4zWmpsI; Path=/
根据服务器返回302响应状态码及location请求头,自动重定向
GET https://target.sit.example.com/
自动触发是否登录检测请求
https://target.sit.example.com/api/tenant/checkLogin
关键请求头
Cookie: JSESSIONID=node0hjccl321oho11ioud9caco7bg14483.node0; _TOKEN_KEY_=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMTM2NzU5OSIsImV4cCI6MTY4MDI2NzE0M30.auqOB37uknCdoleGdEyCjpUoPlrEtsoV4z1p4zWmpsI
关键响应
HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=node01bh0somchrk8d109bhvjeav6ji14490.node0; Path=/
Set-Cookie: _TOKEN_KEY_=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiIwMTM2NzU5OSIsImV4cCI6MTY4MDI2NzE0NH0.qFHISyVRkWcpP7QYkgmb0K32NKhHxUInNQWTNFTfrx0; Path=/ {"msg":"","result":{"accountModifyNum":0,"contacts":"赖大家","email":"","entTenantCode":"WPMJ1d20230317111905","entTenantType":2,"phone":" ] }","registerTime":"2023-03-17","tenantCode":"WPMJ1d20230317111905","tenantType":2,"userAccount":"cNmSiwUONW","userStatus":1,"userType":1},"succ":"ok"}
结合上述请求过程,和开发讨论哪一步导致登录失败,结论是上述第5步,也就是使用ST换取token后。
和前端开发人员沟通,第5步执行完成后,需要将程序返回的token存储到Cookie中,开发截图代码如下

从上图可知,token是在重定向完成后,通过获取浏览器中查询参数获取的,这里对开发提出质疑,这一步能否获取到参数,开发最终验证的结果是可以取到值。
按理,此时代码存储token,按理也是存储到https协议的域名下面,不应该是存到http协议的域名下。所以,提出假设,这里window.localStorage.getItem('loginType')未获取到值,因为这个一开始是访问的http协议的站点时存储到localStorage中的,此时访问的是https协议的站点,跨域了,所以取不到值,导致后续的请求Cookie没有携带对应的Token值。
基于这个假设,让开发去掉获取登录类型的判断,然后构建验证,结果发现成了。
那如何解释,第二次点击登录方式就成功登录呢?此时已经是https协议了,二次点击时不存在跨域问题,重新执行一次登录请求,因为上次登录过Cas,所以不会再调跳转Cas登录页,然后就成功了。
解决方案
一开始和开发讨论,这个是否考虑存储到某个文件,然后从文件读取,或其它者跨域存储方案,后面想一下,直接从接口返回登录类型即可。
网络基础 登录对接CAS-跨域导致的一个意想不到的Bug的更多相关文章
- 来吧学学.Net Core之登录认证与跨域资源使用
序言 学习core登录认证与跨域资源共享是越不过的砍,所以我在学习中同样也遇到啦这两个问题,今天我们就用示例来演示下使用下这2个技术点吧. 本篇主要内容如下: 1.展示一个登录认证的简单示例 2.跨域 ...
- 基于CAS的SSO单点登录-实现ajax跨域访问的自动登录(也相当于超时重连)
先补课,以下网址可以把CAS环境搭起来. [JA-SIG CAS服务环境搭建]http://linliangyi2007.iteye.com/blog/165307 [JA-SIG CAS业务架构介绍 ...
- CAS 跨域原理
http://www.blogjava.net/rain1102/articles/227739.html CAS(Central Authentication Service) 是 Yale 大学发 ...
- 前后端分离下的CAS跨域流程分析
写在最前 前后端分离其实有两类: 开发阶段使用dev-server,生产阶段是打包成静态文件整个放入后端项目中. 开发阶段使用dev-server,生产阶段是打包成静态文件放入单独的静态资源服务器中, ...
- 升级springboot 2.x 踩过的坑——跨域导致session问题
目前IT界主流前后端分离,但是在分离过程中一定会存在跨域的问题. 什么是跨域? 是指浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域. 做过web后台的童鞋都知道,跨 ...
- 访问本地json文件因跨域导致的问题
我使用jquery的getJSON的方法获取本地的json文件,并进行操作,获取json 数据代码如下: $.getJSON("invite_panel.json",functio ...
- Spring Boot+AngularJS中因为跨域导致Session丢失
http://blog.csdn.net/dalangzhonghangxing/article/details/52446821 如果还在为跨域问题烦恼,请查看博主的 解决angular+sprin ...
- 单点登录之ajax跨域实现
需求:相同根域名或不同根域名的两个域名,实现单点登录登出 原理: 以b站为例,b站的账号登录域名为passport.bilibili.com.主站为www.bilibili.com,游戏站为www.b ...
- 跨域导致无法获取cookie
首先我用的框架是vue,请求协议用的是ajax,跨域的处理办法是使用了反向代理,在我之前的博文有详细说明,有兴趣的可以去查看下,在做身份认证权限限制的时候,后台有在http-header的respon ...
- html2canvas - 解决办法之图片跨域导致的截图空白
1. 后端支持:图片要是cdn上的地址,并且允许图片跨域,header头中设置应为 Access-Control-Allow-Origin: * 2. 前端配置 var opts = { scale ...
随机推荐
- 手写Word2vec算法实现
1. 语料下载:https://dumps.wikimedia.org/zhwiki/latest/zhwiki-latest-pages-articles.xml.bz2 [中文维基百科语料] 2. ...
- Qt-FFmpeg开发-音频解码为PCM文件(9)
音视频/FFmpeg #Qt Qt-FFmpeg开发-使用libavcodec API的音频解码示例(MP3转pcm) 目录 音视频/FFmpeg #Qt Qt-FFmpeg开发-使用libavcod ...
- MQTT服务器连接不上的问题
问题描述 环境:阿里云服务器Ubuntu 22.04.3 LTS,安装mosquitto后,在虚拟机端订阅消息出现报错(以前用阿里云Ubuntu20.04 LTS的服务器装上就能用),以下服务器ip是 ...
- 使用jasypt对springboot配置信息加密
1.pom文件增加依赖 <dependency> <groupId>com.github.ulisesbocchio</groupId> <artifactI ...
- ETL工具-nifi干货系列 第九讲 处理器EvaluateJsonPath,根据JsonPath提取字段
1.其实这一节课本来按照计划一起学习RouteOnAttribute处理器(相当于java中的ifelse,switch case 控制语句),但是在学习的过程中遇到了一些问题.RouteOnAttr ...
- ETL工具-nifi干货系列 第六讲 处理器JoltTransformJSON
1.处理器作用 使用Jolt转换JSON数据为其他结构的JSON,成功的路由到'success',失败的'failure'.处理JSON的实用程序不是基于流的,因此大型JSON文档转换可能会消耗大量内 ...
- #define 用法解法
宏的优点是能整理代码 缺点是宏替换来的代码需要人工解除宏后才能暴漏源代码 改底层时候是需要解一解的 它可以做到main函数中只有一个宏字母 这个宏定义时候,定义成了几个函数的源代码 所以main里面就 ...
- k8s节点状态Init:0/1
k8s节点状态Init:0/1 在节点机器上打印日志: journalctl -f -u kubelet 出现以下内容: 5月 29 15:27:34 k8snode2 kubelet[2249]: ...
- LNMP集群架构
网站集群拆分 上一节我们是部署了单机的LNMP,再往下,要进行拆分了,无论是性能.还是安全性,都务必要拆分. 拆分的内容有 nginx集群 mysql nfs共享存储 等 拆分思路 情况1 当前的单机 ...
- 什么是浅拷贝和深拷贝,如何用 js 代码实现?
〇.简介和对比 简介 浅拷贝:只复制原始对象的第一层属性值. 如果属性值是值类型,将直接复制值,本值和副本变更互不影响: 如果是引用数据类型,则复制内存地址,因此原始对象和新对象的属性指向相同 ...