JavaWeb项目Session丢失的问题

标签: 无 分类: 未分类 创建时间:2020-03-05 02:04:57 更新时间:2024-12-03 13:01:37

1.获取session

2.session丢失

业务场景是这样的,从A项目访问链接,会跳到B项目,这是时候从B项目中使用ajax请求A站点的API,就可能造成在A项目中获取不到用户的sessionId。解决方法,可以在跳转B项目时,将sessionId携带在B的链接后面,这样就可以通过url获取到sessionid了。这种情况就是使用前后端分离的模式开发公众号,开发公众号,要先获取用户授权然后跳转到首页。

3.session失效

1
session.invalidate();

4.谷歌浏览器每一次请求的session都不一样的问题

在我使用shiro进行权限认证的时候,每一次登录之后,使用cheklogin进行检查登录状态,总是显示用户未登录。可是在火狐浏览器上就没有这个问题。我才用的是前后端分离的模式进行开放,前台端口为88端口,后台端口为8878,且域名不一样,我把静态页面部署到了ip地址a上,后台服务部署到了ip地址b上,这样就造成了端口和域名都不一样,但是我后台使用spring boot shiro,并且设置了全局跨域,在很长一段时间内,使用谷歌调试都没有什么问题,然后部署到服务器上也没有什么问题,但是最近就出现了总是登录不上的问题。登录之后就会退出,很是奇怪。

然后我打开了谷歌浏览器的记住上一次请求,发现每一次的session都不一样,和参考文章中的情况比较像,于是我就按这个路子去查相关的知识。

(1) 我尝试了在SpringBoot Shiro项目中自定义SessionManager,因为我使用了shiro-spring-boot-web-starter,所有自定义一个SessionManager就好了,不需要在securityManager.setSessionManager(sessionManager()) 了。

1
2
3
4
5
6
7
8
9
10
11
 @Bean
public SessionManager sessionManager() {
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
Cookie cookie = new SimpleCookie(ShiroHttpSession.DEFAULT_SESSION_ID_NAME);
cookie.setHttpOnly(false);
cookie.setSameSite(Cookie.SameSiteOptions.NONE);
sessionManager.setSessionIdCookie(cookie);
sessionManager.setSessionIdCookieEnabled(true);
sessionManager.setSessionIdUrlRewritingEnabled(true);
return sessionManager;
}

(2) 即便这么设置了,也还是不行,因为SameSite=None;还需要带一个Secure标志,所以还需要添加cookie.setSecure(true);

A cookie associated with a cross-site resource at http://120.27.147.231/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.

(3) 添加了cookie.setSecure(true)也是有问题的,如果启用了这个标志,那么cookie就只能通过https进行发送,这就不符合要求了。

(4) 所以最后还是通过nginx进行的转发解决问题,是前后端都在同一个域名以及端口下,然后通过nginx进行端口转发到相应的后台服务中去。

参考文章:
1.chrome浏览器每次请求都会产生一个新的session的问题 (这个问题很像)
2.Cookie 的 SameSite 属性 (何为SameSite属性)
3.Jquery Ajax设置withCredentials解决跨域请求
4.Springboot+Shiro出现SameSite问题 (如何设置SameSite,这里的代码还是需要改,因为使用了一个RedisManager)
5.SpringBoot整合shiro、自定义sessionManager (自定义sessionManager,这是是比较老的项目了,我使用的是shiro-spring-boot-web-starter,稍微有些差别)
6.Integrating Apache Shiro into Spring-Boot Applications (这是官网说明,有点简单了,很多都没有说明白)
7.springboot整合shiro使用shiro-spring-boot-web-starter
8.Apache Shiro SpringBoot 集成原理
9.升级到Chrome 80+的SameSite问题,及Asp.net和aspnetcore站点修改 (这个说了SameSite的原因,以及解决方案,但是给出的是Asp的解决方案)
10.Cookies default to SameSite=Lax (这是官网的解释,似乎没什么用)

(5) 本地开发的时候该如何进行设置呢?可以考虑禁用这个标志
本地开发时,出现跨域问题,虽然后台已经设置了允许跨域访问,但是在前台调试的时候,每一次进行ajax请求,其中的Cookie都不一样,所以我怀疑这是没有根本就没有发送Cookie的问题。解决方法也很简单,就是在Chrome中访问chrome://flags/,搜索SameSite,搜索SameSite,把搜到的结果项都设置为disabled,然后重启浏览器即可。

参考文章:
1.Chrome 80跨域cookie无法携带 (这篇文章说了原理和解决方法)
2.chrome浏览器解决 跨域调试问题
3.Chrome80版本请求接口未携带cookie问题 (这个有图有真相)

5.nginx配置

在使用 Asp.NET 设置cookie之后,查看浏览器Cookie 出现了:This attempt to set a cookie via a Set-Cookie header was blocked becasuse it had the “Secure” attribute but was not received over a secure connection。导致Cookie设置不进去。

[解决]
设置里secure,和默认的samesite=none,那么只能是https才能访问;设置nosecure和strict,可以非https访问。

1
2
3
4
## 通过proxy_cookie_flags
proxy_cookie_flags ~nosecure samesite=strict;
## 或者直接设置cookie_path
proxy_cookie_path / "/; Path=/; Secure; HttpOnly";
参考文章:
1.解决跨域下Cookie的SameSite问题(使用Nginx)
2.nginx添加Set-Cookie属性Secure和HttpOnly proxy_cookie_flags:为cookie设置一个或多个标志。该cookie可以包含文本,变量,以及它们的组合。的 secure, httponly, samesite=strict, samesite=lax, samesite=none 参数添加相应的标志。的 nosecure, nohttponly, nosamesite 参数移除对应的标志。
3.nginx对cookie设置,取消Secure属性 用nginx做反向代理的时候,后台总是收不到session,发现cookie的属性有一个Secure,查阅资料说这个属性会使客户端在发送请求的时候,如果是http,不会带上cookie。去查了官网手册,在1.19.3以后的版本,可以用proxy_cookie_flag实现。 proxy_cookie_flags ~ nosecure; 这个表示去掉所有cookie里的secure属性,
小额赞助
本人提供免费与付费咨询服务,感谢您的支持!赞助请发邮件通知,方便公布您的善意!
**光 3.01 元
Sun 3.00 元
bibichuan 3.00 元
微信公众号
广告位
诚心邀请广大金主爸爸洽谈合作
每日一省
isNaN 和 Number.isNaN 函数的区别?

1.函数 isNaN 接收参数后,会尝试将这个参数转换为数值,任何不能被转换为数值的的值都会返回 true,因此非数字值传入也会返回 true ,会影响 NaN 的判断。

2.函数 Number.isNaN 会首先判断传入参数是否为数字,如果是数字再继续判断是否为 NaN ,不会进行数据类型的转换,这种方法对于 NaN 的判断更为准确。

每日二省
为什么0.1+0.2 ! == 0.3,如何让其相等?

一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3。

每日三省
== 操作符的强制类型转换规则?

1.首先会判断两者类型是否**相同,**相同的话就比较两者的大小。

2.类型不相同的话,就会进行类型转换。

3.会先判断是否在对比 null 和 undefined,是的话就会返回 true。

4.判断两者类型是否为 string 和 number,是的话就会将字符串转换为 number。

5.判断其中一方是否为 boolean,是的话就会把 boolean 转为 number 再进行判断。

6.判断其中一方是否为 object 且另一方为 string、number 或者 symbol,是的话就会把 object 转为原始类型再进行判断。

每日英语
Happiness is time precipitation, smile is the lonely sad.
幸福是年华的沉淀,微笑是寂寞的悲伤。