登录对接CAS-跨域导致的一个意想不到的Bug

背景描述

业务需求是平台登录,接入Cas验证

问题描述

  1. 平台登录页,点击登录方式,跳转Cas登录页,提交登录请求,结果发现,又返回平台登录页;
  2. 再次点击登录方式,登录成功,跳转到目标页面。

问题排查

排查方向-浏览器兼容性问题

这个问题,开发人员在其本地开发环境复现不了,仅在我本机可以,因此,他们初步怀疑,这个是浏览器兼容性问题。开发人员经过一段时间排查,终究没找出问题所在。

排查方向-跨域问题

笔者无意中发现,登录成功后,再次退出登录,然后重复该动作,这种情况下是,问题是不可复现的,但通过点击流量收藏夹中的网址,实现登录时,问题就重现了。

于是,仔细检查了下收藏的网址,发现是网址使用的是http协议,非https,然后我很开心的告诉开发,这种情况下能复现。

经过一番分析后,开发人员得出了结论,就是跨域问题,导致前端获取不到存储到localStorage中的Token(最终会存储为Cookie),所以访问后端时,没有携带该token值,最终登录失败,并基于此准备一些相对复杂的解决方案。

根因分析与解决方案

根因分析

结合自己的分析,及开发的解释,依旧是云里雾里,感觉开发没有说清楚里面的逻辑,终不能说服自己,于是结合请求过程,同开发进行二次探讨。

以下是整个操作过程中,笔者抓取的一些关键请求信息

  1. 访问前台页面
GET http://target.sit.example.com/
  1. 自动触发登录检测请求

    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"}
  2. 检测结果为未登录,程序根据目标平台提示,跳转Cas登录页

    GET https://wcas.sit.example.com/cas/login?service=https%3A%2F%2Fmg.sit.example.com%2Fapi%2Fadmin%2Flogin%3FloginType%3DCAS-DATA
  3. 提交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
  4. 根据服务器返回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=/
  5. 根据服务器返回302响应状态码及location请求头,自动重定向

    GET https://target.sit.example.com/
  6. 自动触发是否登录检测请求

    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的更多相关文章

  1. 来吧学学.Net Core之登录认证与跨域资源使用

    序言 学习core登录认证与跨域资源共享是越不过的砍,所以我在学习中同样也遇到啦这两个问题,今天我们就用示例来演示下使用下这2个技术点吧. 本篇主要内容如下: 1.展示一个登录认证的简单示例 2.跨域 ...

  2. 基于CAS的SSO单点登录-实现ajax跨域访问的自动登录(也相当于超时重连)

    先补课,以下网址可以把CAS环境搭起来. [JA-SIG CAS服务环境搭建]http://linliangyi2007.iteye.com/blog/165307 [JA-SIG CAS业务架构介绍 ...

  3. CAS 跨域原理

    http://www.blogjava.net/rain1102/articles/227739.html CAS(Central Authentication Service) 是 Yale 大学发 ...

  4. 前后端分离下的CAS跨域流程分析

    写在最前 前后端分离其实有两类: 开发阶段使用dev-server,生产阶段是打包成静态文件整个放入后端项目中. 开发阶段使用dev-server,生产阶段是打包成静态文件放入单独的静态资源服务器中, ...

  5. 升级springboot 2.x 踩过的坑——跨域导致session问题

    目前IT界主流前后端分离,但是在分离过程中一定会存在跨域的问题. 什么是跨域? 是指浏览器从一个域名的网页去请求另一个域名的资源时,域名.端口.协议任一不同,都是跨域. 做过web后台的童鞋都知道,跨 ...

  6. 访问本地json文件因跨域导致的问题

    我使用jquery的getJSON的方法获取本地的json文件,并进行操作,获取json 数据代码如下: $.getJSON("invite_panel.json",functio ...

  7. Spring Boot+AngularJS中因为跨域导致Session丢失

    http://blog.csdn.net/dalangzhonghangxing/article/details/52446821 如果还在为跨域问题烦恼,请查看博主的 解决angular+sprin ...

  8. 单点登录之ajax跨域实现

    需求:相同根域名或不同根域名的两个域名,实现单点登录登出 原理: 以b站为例,b站的账号登录域名为passport.bilibili.com.主站为www.bilibili.com,游戏站为www.b ...

  9. 跨域导致无法获取cookie

    首先我用的框架是vue,请求协议用的是ajax,跨域的处理办法是使用了反向代理,在我之前的博文有详细说明,有兴趣的可以去查看下,在做身份认证权限限制的时候,后台有在http-header的respon ...

  10. html2canvas - 解决办法之图片跨域导致的截图空白

    1. 后端支持:图片要是cdn上的地址,并且允许图片跨域,header头中设置应为 Access-Control-Allow-Origin:  * 2. 前端配置 var opts = { scale ...

随机推荐

  1. Html简要笔记

    html在线文档: https://www.w3school.com.cn 怎么创建文件我已经会了 1,html快速入门 <!--文档类型说明 注释 --> <!DOCTYPE ht ...

  2. MySQL查看实时执行的SQL语句

    MySQL默认不能实时查看执行的SQL语句,因为这会消耗一定的资源. 要开启这个功能,稍微配置一下,打开这个LOG记录就可以了. 1 查看LOG功能 首先,查看是否已经开启实时SQL语句记录. mys ...

  3. Vue CLI 4与项目构建实战指南

    title: Vue CLI 4与项目构建实战指南 date: 2024/6/9 updated: 2024/6/9 excerpt: 这篇文章介绍了如何使用Vue CLI优化项目构建配置,提高开发效 ...

  4. java.io.File类中分隔符区别

    1.separator File.separator是系统默认的文件分隔符号,在UNIX系统上,这个字段的值是'/';在Microsoft Windows系统上,它是''. 类型:String 2.s ...

  5. The model backing the 'MainDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

    The model backing the 'MainDbContext' context has changed since the database was created. Consider u ...

  6. Maven常用命令有哪些?

    a.install 本地安装, 包含编译,打包,安装到本地仓库编译 - javac 打包 - jar, 将java代码打包为jar文件 安装到本地仓库 - 将打包的jar文件,保存到本地仓库目录中. ...

  7. spring项目中读取resources下的文件

    spring项目中读取resources下的文件 我们都知道,spring项目经过maven打包后,可以打成jar包或可解压的war包 a. war包是需要外置的web容器去运行的,是需要先解压的 b ...

  8. http请求方式GET,POST工具类RestTemplate

    http请求方式GET,POST工具类RestTemplate import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.serial ...

  9. MoneyPrinterPlus:AI自动短视频生成工具-阿里云配置详解

    MoneyPrinterPlus是一个很好的自动短视频生成工具,虽然是一个非常好的工具,但是有些小伙伴可能不太清楚具体应该如何配置才能让它跑起来. 因为MoneyPrinterPlus依赖一些具体的配 ...

  10. Wakelocks 框架设计与实现

    Wakelocks 框架是基于Wakeup Source实现的为Android系统上层提供投票机制,以阻止系统进入休眠. 1.功能说明 该模块的支持受宏CONFIG_PM_WAKELOCKS控制.在使 ...