昨天晚上想解决一个springboot应用中session失效的问题,源于公司生产环境目前是一台服务器部署两个
tomcat,应用通过同一个ip访问的时候session会互相冲突。我在网上找了几个解决方案,要么是在tomcat
中
server配置上添加servlet.sesssion.cookie.name属性,但是这两个我修改后都不见效,最后还把tomcat源码
下载了下来,看它里面的代码是这么写的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | private static String getConfiguredSessionCookieName(Context context) { // Priority is: // 1. Cookie name defined in context // 2. Cookie name configured for app // 3. Default defined by spec if (context != null) { String cookieName = context.getSessionCookieName(); if (cookieName != null && cookieName.length() > 0) { return cookieName; } SessionCookieConfig scc = context.getServletContext().getSessionCookieConfig(); cookieName = scc.getName(); if (cookieName != null && cookieName.length() > 0) { return cookieName; } } return null; } |
先从context获取sessionCookieName,如果没有那么再从应用的servletContext中获取sessionCookieConfig,看来我们的思路貌似是
没问题的,但是为什么就不生效呢?在浏览器里看cookieName还是
今早醒来突然想到我们的springboot应用里是根据shiro框架来实现权限和会话管理的,会不会跟这个有关系呢?脑子里突然想到这个应该是个
正确的解决方向,于是乎爬起来看了下工程代码,不看不知道,一看就知道应该就是这边的问题,我们看到shiro框架里的
是这么写的:
1 2 3 4 5 6 7 | public DefaultWebSessionManager() { Cookie cookie = new SimpleCookie("JSESSIONID"); cookie.setHttpOnly(true); this.sessionIdCookie = cookie; this.sessionIdCookieEnabled = true; this.sessionIdUrlRewritingEnabled = true; } |
到这里就明白了,为啥我们改了tomcat也改了springboot本身的配置不起效果,就是因为我们是通过shiro来控制用户会话和权限控制的,
所以相当于是shiro把tomcat还有spring内部的cookie给替代了,那么我们只要定义一个bean继承自shiro的cookie注入然后放入shiro不就行了。
1 2 3 4 | @Component @ConfigurationProperties(prefix = "shiro.cookie") public class ShiroCookie extends SimpleCookie { } |
问题到这就迎刃而解了,所以我们解决问题的时候也不能在一个方向钻牛角尖,有时候答案可能就在眼前,需要我们转变思路,
换个角度思考有可能就豁然开朗了,另外看源码确实可以一定程度上提高我们解决问题的效率。
参考资料:
- 在Intellij idea下为tomcat7设置sessionCookieName
- tomcat修改jsessionid在cookie中的名称
- Spring boot 去除URL 里的 JSESSIONID
欢迎大家关注我的个人公众号: