两个不同应用Session能互相访问解决

问题分析

两个应用部署在同一个服务器上,默认情况下会共享同一个 Tomcat 容器,因此它们的 session 也会共用同一个存储空间。当系统 B 登录后,系统 B 的登录用户信息被写入 session;此时访问系统 A 时,由于两个应用共享 session,系统 A 的拦截器自然能读到系统 B 写入的用户信息,从而误判为已登录。

java 复制代码
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    User u = (User) request.getSession().getAttribute("user");
    if (u != null) {
        return true;
    }
    return false;
}

解决方案

要解决两个应用 session 互相访问的问题,核心思路是让两个应用使用各自独立的 session,互不干扰。常见做法有以下几种:

方案一:修改应用上下文路径

这是最简单直接的方式。将两个应用部署在不同的上下文路径下,Tomcat 会为不同上下文分配独立的 session 空间,两个应用之间互不干扰。

具体步骤如下:

  1. 打开 Tomcat 的 conf/server.xml 配置文件。
  2. <Host> 节点下找到 <Context> 配置,为系统 A 和系统 B 分别配置不同的 path 属性,例如:
xml 复制代码
<Context path="/systemA" docBase="/opt/apps/systemA" reloadable="true" />
<Context path="/systemB" docBase="/opt/apps/systemB" reloadable="true" />
  1. 保存配置后重启 Tomcat 服务。
  2. 此时系统 A 的访问地址为 http://服务器IP:端口/systemA,系统 B 的访问地址为 http://服务器IP:端口/systemB,两个应用各自拥有独立的 session,互不影响。

如果两个应用必须部署在同一个上下文路径下,可以通过为两个应用设置不同的 session cookie 名称来避免 session 串用。

具体步骤如下:

  1. 在系统 A 的 web.xml 中配置独立的 session cookie 名称:
xml 复制代码
<session-config>
    <cookie-config>
        <name>JSESSIONID_A</name>
    </cookie-config>
</session-config>
  1. 在系统 B 的 web.xml 中配置另一个独立的 session cookie 名称:
xml 复制代码
<session-config>
    <cookie-config>
        <name>JSESSIONID_B</name>
    </cookie-config>
</session-config>
  1. 如果使用 Spring Boot 内嵌 Tomcat,可以在 application.yml 中配置:
yaml 复制代码
server:
  servlet:
    session:
      cookie:
        name: JSESSIONID_A   # 系统 A 使用
  1. 重启两个应用后,浏览器会为系统 A 和系统 B 分别保存不同的 session cookie,系统 A 的拦截器只能读取到系统 A 自己的 session,不会再误读到系统 B 的登录信息。

方案三:使用独立的 session 存储

如果两个应用必须共享容器,且需要更灵活的 session 管理,可以为两个应用分别配置独立的 session 存储介质,例如不同的 Redis 库。

具体步骤如下:

  1. 在系统 A 的 Spring Boot 配置中,指定使用 Redis 的 0 号库存储 session:
yaml 复制代码
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 0
  session:
    store-type: redis
  1. 在系统 B 的 Spring Boot 配置中,指定使用 Redis 的 1 号库存储 session:
yaml 复制代码
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    database: 1
  session:
    store-type: redis
  1. 重启两个应用后,系统 A 的 session 写入 Redis 0 号库,系统 B 的 session 写入 Redis 1 号库,两个应用的 session 数据完全隔离。
  2. 系统 A 的拦截器在读取 session 时,只会从 0 号库读取,因此无法获取到系统 B 的登录信息。
相关推荐
带多刺的玫瑰1 小时前
Leecode#35刷题之搜索插入位置
java·python·算法
一条泥憨鱼1 小时前
苍穹外卖【day10| 来电提醒和客户催单】
java·后端·websocket·苍穹外卖
SunnyDays10111 小时前
Java 设置 Excel 数据验证:整数、日期、文本长度、下拉列表和时间
java·excel·数据验证·下拉列表
编程_大白1 小时前
@SpringBootTest
java
刘天远1 小时前
Agent最小权限实现:策略表、临时令牌与撤权回归
java·jvm·人工智能·sqlite
QQ_21696290961 小时前
基于SpringBoot+Vue的小生活平台的设计与实现
java·数据库·vue.js·spring boot·spring·微信小程序·生活
前端兰博2 小时前
06-并发
java
程序员-珍2 小时前
Android studio 突然打不开
android·java
重生之小比特2 小时前
【Java SE】字符串 - String类
java·开发语言·intellij-idea