登录对接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. 源码分析——MyBatis与Spring整合后如何保证SqlSession线程安全

    在MyBatis架构中SqlSession是提供给外层调用的顶层接口,它是MyBatis对外暴露的最重要的接口,用户通过该接口即可完成数据库的全部操作.在上文中我们明白了我们常用的Mybatis动态代 ...

  2. zabbix笔记_006 zabbix web监控

    web监控 web监控是对http网站服务进行监控,模拟用户访问网站,对特定的结果进行告警,通知管理员网站状态. web监控是运维必备知识点,通过实验能够熟悉配置和了解zabbix是如何监控web站点 ...

  3. itest(爱测试)开源接口测试&敏捷测试&极简项目管理 7.1.0 发布,ui优化及bug修复

    (一)itest 简介及更新说明 itest 开源敏捷测试管理,testOps 践行者,极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试,接口Mock 6合1,又有丰富的统计分析.可按测试包 ...

  4. kettle从入门到精通 第五十三课 ETL之kettle MQTT/RabbitMQ producer 实战

    1.MQTT介绍 MQTT (Message Queuing Telemetry Transport) 是一种轻量级的消息传输协议,设计用于连接低带宽.高延迟或不可靠网络的设备. MQTT 是基于发布 ...

  5. C# .NET MVC 表单提交前校验数据等

    页面上写2个button,一个普通button,另一个是submit,submit的这个隐藏.校验函数写在普通button里,普通button click函数中去提交表单. 页面: <input ...

  6. 开源高性能结构化日志模块NanoLog

      最近在写数据库程序,需要一个高性能的结构化日志记录组件,简单研究了一下Microsoft.Extensions.Logging和Serilog,还是决定重造一个轮子. 一.使用方法   直接参考以 ...

  7. Linux设置时区

    引言 在linux安装好了过后,如果时区不正确,需要手动地对它设置我们需要的时区 设置 控制台输入tzselect,回车 tzselect 2.然后选择 5 "Asia" 亚州,回 ...

  8. 在线RSA公钥私钥生成工具

    在线RSA非对称加密公钥私钥生成工具,提供便捷.安全的公私钥生成服务.支持多种密钥长度选择,满足个性化需求.一键生成PEM格式证书,让您快速实现数据加密与身份验证,保障数据安全,提升网络安全防护能力. ...

  9. mongodb创建索引和删除索引和背景索引background

    mongodb创建索引和删除索引和背景索引background MongoDB的背景索引允许在后台创建和重建索引,而不会对数据库的正常操作产生影响.背景索引的创建过程是非阻塞的,可以在业务运行时创建或 ...

  10. AES加密和解密,key需要32位

    AES加密和解密,key需要32位 package com.example.core.mydemo.sign; import org.apache.commons.codec.binary.Base6 ...