登录cookie检查失败是什么意思(一个诡异的登录问题)

首页教程更新时间:2023-02-03 21:59:56

美好周末,从解 BUG 开始!

周五本来想早点下班,临了有一个简单的需求突然提上来,心想着整完了就走,没想到一下折腾了 1 个多小时才搞定,愉快的周末就从加班中开启了。回到家里把这件事复盘一下,小伙伴们看看是否能够从中 GET 到一些未知的东西。

需求是这样的:

项目是 Spring Boot 项目,里边对请求进行了划分,有的请求是 HTTP 协议,有的请求是 HTTPS 协议,项目规定,有一些请求必须是 HTTPS 协议,例如 /https 接口,该接口必须使用 HTTPS 协议访问,如果用户使用了 HTTP 协议访问,那么会自动发生请求重定向,重定向到 HTTPS 协议上;同时也有一些请求必须是 HTTP 协议,例如 /http 接口,该接口必须使用 HTTP 协议访问,如果用户使用了 HTTPS 协议访问,那么会自动发生请求重定向,重定向到 HTTP 协议上。对于一些没有明确规定的接口,当用户访问 HTTP 协议时,不需要自动跳转到 HTTPS 协议上,即用户如果使用 HTTP 协议就是 HTTP 协议,用户如果使用 HTTPS 协议就是 HTTPS 协议。

这个任务实在是小 case,由于项目本身已经支持 HTTPS 了,我只需要再添加一个 HTTP 监听的端口即可(Spring Boot 中配置 Https),添加如下配置:

@Configuration publicclassTomcatConfig{ @Bean TomcatServletWebServerFactorytomcatServletWebServerFactory(){ TomcatServletWebServerFactoryfactory=newTomcatServletWebServerFactory(); factory.addAdditionalTomcatConnectors(createTomcatConnector()); returnfactory; } privateConnectorcreateTomcatConnector(){ Connectorconnector=new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(8080); returnconnector; } }

添加完成后,项目启动日志如下:

登录cookie检查失败是什么意思,一个诡异的登录问题(1)

可以看到,项目已经同时支持 HTTPS 和 HTTP 了,两者分别在不同的端口上监听。

接下来利用 Spring Security 中的 HTTPS 校验转发功能对请求进行区分:

@Configuration publicclassSecurityConfigextendsWebSecurityConfigurerAdapter{ @Override protectedvoidconfigure(HttpSecurityhttp)throwsException{ http. //省略其他 .requiresChannel() .antMatchers("/https").requiresSecure() .antMatchers("/http").requiresInsecure() .and() .csrf().disable(); } }

大功告成,so easy!

配置完成后,启动项目,如下两个地址都可以访问到登录页面:

可以使用任意一个地址登录。

假如使用了 HTTP 协议登录,登录成功后,如果直接访问 http://localhost:8080/http 请求,可以直接访问到,没有任何问题;如果登录成功后访问 http://localhost:8080/https 请求,则会自动重定向到 https://localhost:8444/https,一切看起来都很完美。

似乎可以下班了。

别急,我再用 HTTPS 登录测试了,打开 https://localhost:8444/login 页面,登录成功,请求 https://localhost:8444/https 地址没有问题,请求 https://localhost:8444/http ,傻眼了。

当我使用 HTTPS 登录成功后,请求 https://localhost:8444/http 地址时,按理说会重定向到 http://localhost:8080/http,结果并没有,而是重定向到登录页面,这是咋回事?更为诡异的是,现在在登录页面,无论我怎么做,都登录失败。

看来 965 到底是海市蜃楼,还是继续解决问题吧。

那就从登录开始,好端端的为什么突然就无法登录了呢?

先清除浏览器缓存试试?咦,清除浏览器缓存后登录成功了!

经过多次尝试后,我总结出来了如下规律:

如果使用 HTTP 协议登录,登录成功后,HTTP 协议和 HTTPS 协议之间互相重定向没有任何问题。如果使用了 HTTPS 协议登录,登录成功后,HTTPS 协议重定向到 HTTP 协议时,需要重新登录,并且在登录页面总是登录失败,需要清除浏览器缓存才能登录成功。

先找到规律这个很重要,有的小伙伴微信问松哥问题时候,喜欢说,这个东西它一会可以一会又不行,老实说,这个问题提的非常业余!所有看似无规律的 BUG 背后都是有规律的,找到规律才是解决 BUG 的第一步。

在整个过程中,最为诡异的是从 HTTPS 重定向到 HTTP 之后,无论怎么样都登录不了,服务端重启也没用,只能清除浏览器缓存,这个非常奇怪,我觉得就先从这个地方入手 DEBUG。

那就 DEBUG,浏览器发送登录请求,服务端我把 Spring Security 登录流程走了一遍,貌似没问题,登录成功后重定向到 http://localhost:8080/ ,这也是正常的,继续 DEBUG,重定向到 http://localhost:8080/ 地址时,出现了一点点意外,该请求在 Spring Security 过滤器链的最后一个环节 FilterSecurityInterceptor 中执行时候抛出异常了,异常原因是因为检查用户身份,发现这是个匿名用户!(一文搞定 Spring Security 异常处理机制!)

不对呀,一开始已经登录成功了,怎么会是匿名用户呢?Spring Security 在登录成功后,会将用户信息保存在 SecurityContextHolder 中(在 Spring Security 中,我就想从子线程获取用户登录信息,怎么办?),是不是没保存?重新检查登录过程,发现登录成功后是保存了用户信息的。但是当登录成功后再次发送请求却说我没登录,还剩一种可能,是不是前端请求的问题,JSESSIONID 拿错了?或者没拿?

浏览器 F12 检查前端请求,发现登录成功后,重定向到 http://localhost:8080/ 地址时,果然没有携带 Cookie!

现在的问题是为什么它就不携带 Cookie 呢?

一瞬间脑子里闪过了诸多可能性,是不是浏览器 SameSite 机制导致的?是不是。。。最后思维定格在 Cookie 的 Secure 标记上。

如果请求是 HTTPS,则服务端响应的 Cookie 中含有 Secure 标记:

登录cookie检查失败是什么意思,一个诡异的登录问题(2)

这个标记表示该 Cookie 只可以在安全环境下(HTTPS)传输,如果请求是 HTTP 协议,则不会携带该 Cookie。这样就能解释通为什么登录成功后重定向时不携带 Cookie 了。

新的问题来了,我使用的是 HTTP 协议登录,为什么 Cookie 中有 Secure 标记呢?回答这个问题,我们要完整的梳理一遍登录过程。

首先我们使用 HTTPS 协议登录,登录成功后,返回的 Cookie 中含有 Secure 标记,接下来我们访问 https://localhost:8444/http,该请求重定向到 http://localhost:8080/http,重定向的请求是 HTTP 请求,而 Cookie 只可以在 HTTPS 环境下传输,所以不会携带 Cookie,服务端以为这是一个匿名请求,所以要求重定向到登录页面,回到登录页面继续登录,此时发起的登录是 HTTP 请求,即端口是 8080,由于 Cookie 并不会区分端口号,所以使用 8080 登录成功后,使用的还是之前 8444 生成的 Cookie,但是 8080 又无法在发送请求时,自动携带该 Cookie,所以看到的就是总是登录失败,当清除浏览器缓存后,8444 的 Cookie 就被清除了,8080 再次登录就可以生成自己的没有 Secure 标记的 Cookie,此时一切又恢复正常了。

这里边其实主要涉及到两个知识点:

  1. 含有 Secure 标记的 Cookie 只可以在安全环境下(HTTPS)传输。
  2. Cookie 是不区分端口号的,如果 Cookie 名相同,会自动覆盖,并且读取的是相同的数据。所以 8080 和 8444 并不会自动使用两个 Cookie。

至此,总算搞清楚这个诡异的登录问题了。那么接下来的解决方案就很容易了。

还是那句话,所有看似无规律的 BUG 都是有规律的,找到规律才有解决问题的可能性!

,
图文教程
相关文章
热门专题
推荐软件
奇热小说
奇热小说
下载
QQ2019手机版
QQ2019手机版
下载
王者荣耀
王者荣耀
下载
百度浏览器迷你版
百度浏览器迷你版
下载
2345浏览器手机版
2345浏览器手机版
下载
网易邮箱
网易邮箱
下载
爱奇艺
爱奇艺
下载
网易云音乐
网易云音乐
下载
WPSOffice
WPSOffice
下载
优酷
优酷
下载
谷歌浏览器(Chrome)
谷歌浏览器(Chrome)
下载
迅雷看看播放器
迅雷看看播放器
下载
UC浏览器
UC浏览器
下载
QQ音乐
QQ音乐
下载
阿里旺旺买家版v9.12.10C官方版
阿里旺旺买家版v9.12.10C官方版
下载
360安全卫士v12.1官方版
360安全卫士v12.1官方版
下载
猜你喜欢
流量码头
流量码头
下载
城市工程师
城市工程师
下载
北京预约挂号
北京预约挂号
下载
乐里斗V1.0.6.1官方完整版
乐里斗V1.0.6.1官方完整版
下载
FiledropMac版V1.1.5
FiledropMac版V1.1.5
下载
星露谷物语农场房屋mod
星露谷物语农场房屋mod
下载
网络卫士
网络卫士
下载
精灵工匠
精灵工匠
下载
衣脉合成电脑版
衣脉合成电脑版
下载
京东HR电子签
京东HR电子签
下载
福利来袭高级版
福利来袭高级版
下载
环世界1.0修复工作台MOD
环世界1.0修复工作台MOD
下载
乱世征途送充版
乱世征途送充版
下载
ps花纹心形笔刷
ps花纹心形笔刷
下载
苏伊士运河挑战
苏伊士运河挑战
下载
狐妖小红娘
狐妖小红娘
下载