一、个人理解的web应用登录流程大概是以下几个步骤(省略了很多细节。。:
用户浏览器中发送登录请求 ->
若认证通过,后端响应中带上set-cookie给浏览器。其中cookie中有专属该用户的jsessionid ->
浏览器保存cookie,并且在后续请求中带上cookie ->
服务器收到后续请求,首先判断cookie中的jsessionid是否有效。若无效,返回403;若有效,处理该请求 ->
继续处理,直到Session失效
二、Spring Session
由于项目部署的机器不止一台,并且每台机器上可能有多个po,同一个用户的请求可能会分配在不同的机器或者po上。
为保证同一个用户访问系统能正常进行,使用了Spring Session实现session共享。
Spring Session原理大致是,把原来保存在具体某个web服务器中的Session,经过过滤器,保存在redis中。后续请求的Session读取都从redis中拿
1、使用方法:
- 引入Spring Session 依赖。(忽略了版本号。。
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
- 启动类或者同级目录下的配置类中使用@EnableRedisHttpSession 注解,开启Spring Session支持
- application.yml配置文件中增加redis服务的配置
spring:
redis:
host: localhost
port: 6379
password: pwd123
以上就好了。。
2、因为session保存在Redis中,所以即使服务器重启了,用户不重新登录,等服务器起好后,只要不清浏览器的cookie,也是可以正常登录的。
3、可以直接在注解中指定Session过期时间:@EnableRedisHttpSession(maxInactiveIntervalInSeconds= 1800) 单位:秒
如果不设置过期时间,Redis中的Session可能会越来越多,可以考虑使用定时任务定期删除。
三、相关问题
1、最近出现的一个问题是,测试环境登录,除了登录的接口,后续接口立马出现403 认证失败异常。
- 发现有一种场景的确会有问题:
同一个浏览器中,首先登录测试环境,然后再登录生产环境,再回到测试环境的页面操作,接口就会出现403异常。
- 原因:
测试环境和生产环境的cookie中,jsessionid的name和domain都是相同的。若在同一个浏览器中同时打开两个环境,会发生cookie串用的情况。
上面的场景,回到测试环境处理请求时,后端接受到的jsessionid其实是生产环境的,测试环境的服务器不认识,就认为是非法用户了。
- 解决方法:
想到的一种办法是,不同环境设置不同的cookie name