同时使用两个 spring 启动应用程序时退出一个 spring 应用程序
Logged out of one spring app when using two spring boot apps at the same time
我有两个 spring 启动应用程序。
- module1 运行 端口 8080
- module2 运行 在端口 9090
我已经在 application.properties 文件
中使用这个 属性 设置了端口
server.port=${port:9090}
两个模块都有 /login、/signup,无需通过以下代码完成身份验证即可访问。
http.authorizeRequests()
.antMatchers("/signup", "/login").permitAll()
任何其他请求都需要对用户进行身份验证。
如果我一次使用一个模块就没有问题,
但是如果尝试同时来回使用它们,那么问题是我每次使用另一个应用程序时都必须重新登录到上一个应用程序。
例如
- 转到模块 1 的登录页面 -(Header 响应已设置 jsessionid=XX)ok
- 登录模块 1 - 正常
- 浏览模块 1 上的受保护内容 - 正常
- 转到模块 2 上的注册页面 -(Header 响应已设置 jsessionid=YY)ok
- 尝试浏览到模块 1 上的另一个安全内容 - 我必须重新登录
我很确定这是因为 jessionid 被 module2 重置了。
我读过这篇文章,其中指出 cookie 不是特定于端口的。
但必须有一个解决方案,这样我就不必每次切换应用程序时都必须登录。
您需要为两个应用程序使用不同的 cookie 名称。
有不同的方法可以做到这些,最简单的方法是,对于版本 >=1.3 的 spring-boot 应用程序,只需设置 属性 :
server.session.cookie.name = MYSESSIONID
其他方法在本 post 中描述。
将您的应用程序映射到不同的上下文路径,因此 JSESSIONID
cookie 将是独立的;否则,cookie 用于相同的上下文,因此两个应用程序实际上有一个 cookie。另一种解决方案是使用不同的主机。
请注意,您不仅要在此处更改 cookie 的上下文路径:如果您更改应用程序的上下文路径,Servlet API 实现将为您处理 cookie 上下文路径更改。
我对相同的主机和不同的上下文路径进行了一些试验。
我目前正在启动两个应用程序,它们都以 Servlet API 作为基础(JSESSIONID cookie 由 Servlet API 的会话机制定义)。这些应用程序都 运行 在本地主机上,在不同的端口上,并且具有不同的上下文(/app1 和 /app2)。我登录了这两个应用程序,在 Chrome 的列出 cookie 的对话框中,我可以看到两个 JSESSIONID cookie:一个用于 localhost
和 /app1
,另一个用于 localhost
和/app2
.
然后我在 /app2 中注销。它的 JSESSIONID 被销毁并用不同的内容重新创建(因为我再次被重定向到登录页面)。 (请注意,要看到更改,我必须关闭 Cookies 对话框并重新打开它,因为 Chrome 没有即时更新它)。同时,属于 /app1 的 JSESSIONID cookie 完好无损,我可以继续在 /app1 中工作(所以我没有从中退出)。
更新
再做一个实验。我已将这两个应用程序映射到同一上下文 (/app1)。他们 运行 在 localhost:8084 和 localhost:8085 上。我执行以下操作:
- 我登录到第一个应用程序(端口 8084)
- 我登录到第二个应用程序(端口 8085)
- 我切换回第一个应用程序选项卡,单击任何 link 并看到会话已被销毁(因为我被重定向到登录页面)。
因此,即使应用程序 运行 在具有相同上下文路径的同一主机的不同端口上,它们也会使用相同的 cookie。基本上,这就是 中所说的:Cookie 不提供端口隔离
小结:
- 不同主机:没问题,cookie不同
- 不同的应用程序上下文:没问题,cookie 不同
- 同一个主机,同一个应用程序上下文,不同的端口:只有一个cookie,这会导致冲突。
所以食谱和之前一样:
- 要么使用不同的主机(即主机名,不包括端口)
- 或者使用不同的上下文路径
- 或者(如另一个答案所建议的那样)更改 cookie 名称以避免冲突
我有两个 spring 启动应用程序。
- module1 运行 端口 8080
- module2 运行 在端口 9090
我已经在 application.properties 文件
中使用这个 属性 设置了端口server.port=${port:9090}
两个模块都有 /login、/signup,无需通过以下代码完成身份验证即可访问。
http.authorizeRequests()
.antMatchers("/signup", "/login").permitAll()
任何其他请求都需要对用户进行身份验证。
如果我一次使用一个模块就没有问题,
但是如果尝试同时来回使用它们,那么问题是我每次使用另一个应用程序时都必须重新登录到上一个应用程序。 例如
- 转到模块 1 的登录页面 -(Header 响应已设置 jsessionid=XX)ok
- 登录模块 1 - 正常
- 浏览模块 1 上的受保护内容 - 正常
- 转到模块 2 上的注册页面 -(Header 响应已设置 jsessionid=YY)ok
- 尝试浏览到模块 1 上的另一个安全内容 - 我必须重新登录
我很确定这是因为 jessionid 被 module2 重置了。
我读过这篇文章,其中指出 cookie 不是特定于端口的。
但必须有一个解决方案,这样我就不必每次切换应用程序时都必须登录。
您需要为两个应用程序使用不同的 cookie 名称。
有不同的方法可以做到这些,最简单的方法是,对于版本 >=1.3 的 spring-boot 应用程序,只需设置 属性 :
server.session.cookie.name = MYSESSIONID
其他方法在本 post 中描述。
将您的应用程序映射到不同的上下文路径,因此 JSESSIONID
cookie 将是独立的;否则,cookie 用于相同的上下文,因此两个应用程序实际上有一个 cookie。另一种解决方案是使用不同的主机。
请注意,您不仅要在此处更改 cookie 的上下文路径:如果您更改应用程序的上下文路径,Servlet API 实现将为您处理 cookie 上下文路径更改。
我对相同的主机和不同的上下文路径进行了一些试验。
我目前正在启动两个应用程序,它们都以 Servlet API 作为基础(JSESSIONID cookie 由 Servlet API 的会话机制定义)。这些应用程序都 运行 在本地主机上,在不同的端口上,并且具有不同的上下文(/app1 和 /app2)。我登录了这两个应用程序,在 Chrome 的列出 cookie 的对话框中,我可以看到两个 JSESSIONID cookie:一个用于 localhost
和 /app1
,另一个用于 localhost
和/app2
.
然后我在 /app2 中注销。它的 JSESSIONID 被销毁并用不同的内容重新创建(因为我再次被重定向到登录页面)。 (请注意,要看到更改,我必须关闭 Cookies 对话框并重新打开它,因为 Chrome 没有即时更新它)。同时,属于 /app1 的 JSESSIONID cookie 完好无损,我可以继续在 /app1 中工作(所以我没有从中退出)。
更新
再做一个实验。我已将这两个应用程序映射到同一上下文 (/app1)。他们 运行 在 localhost:8084 和 localhost:8085 上。我执行以下操作:
- 我登录到第一个应用程序(端口 8084)
- 我登录到第二个应用程序(端口 8085)
- 我切换回第一个应用程序选项卡,单击任何 link 并看到会话已被销毁(因为我被重定向到登录页面)。
因此,即使应用程序 运行 在具有相同上下文路径的同一主机的不同端口上,它们也会使用相同的 cookie。基本上,这就是 中所说的:Cookie 不提供端口隔离
小结:
- 不同主机:没问题,cookie不同
- 不同的应用程序上下文:没问题,cookie 不同
- 同一个主机,同一个应用程序上下文,不同的端口:只有一个cookie,这会导致冲突。
所以食谱和之前一样:
- 要么使用不同的主机(即主机名,不包括端口)
- 或者使用不同的上下文路径
- 或者(如另一个答案所建议的那样)更改 cookie 名称以避免冲突