springboot应用在同IP下Session冲突的解决思路

昨天晚上想解决一个springboot应用中session失效的问题,源于公司生产环境目前是一台服务器部署两个
tomcat,应用通过同一个ip访问的时候session会互相冲突。我在网上找了几个解决方案,要么是在tomcat
conf/context.xml中Context元素上添加一个sessionCookieName属性,要么是在springboot
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还是JSESSIONID, 一时半会找不到答案。但是想想解决思路应该是没问题的,最终目的要把cookie名称给修改掉。

今早醒来突然想到我们的springboot应用里是根据shiro框架来实现权限和会话管理的,会不会跟这个有关系呢?脑子里突然想到这个应该是个
正确的解决方向,于是乎爬起来看了下工程代码,不看不知道,一看就知道应该就是这边的问题,我们看到shiro框架里的DefaultWebSessionManager
是这么写的:

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 {
    }

问题到这就迎刃而解了,所以我们解决问题的时候也不能在一个方向钻牛角尖,有时候答案可能就在眼前,需要我们转变思路,
换个角度思考有可能就豁然开朗了,另外看源码确实可以一定程度上提高我们解决问题的效率。

参考资料:

  1. 在Intellij idea下为tomcat7设置sessionCookieName
  2. tomcat修改jsessionid在cookie中的名称
  3. Spring boot 去除URL 里的 JSESSIONID

欢迎大家关注我的个人公众号:
在这里插入图片描述