- 1 概述
- 2 实现方法
- 3 测试方法
Session并发控制指服务端控制客户端某个用户同时在线的数量,如某个账号在谷歌浏览器上进行了登陆,又在IE浏览器上进行了登陆,又在手动app上进行了登陆,那这时session并发数就是3.控制session并发的意思一是在于控制服务器资料占用,二是可以起到对帐号的保护作用。比较我们是不是都有这样的经历,我们正登着QQ呢,突然自己登出了,不久QQ就给我们发了一条消息,说你的帐号在哪哪哪登陆了,如果不是本人 *** 作赶快修改密码。这就是session并发控制。如果没有session并发控制,那么你的帐号被他人登陆后,那么你将毫无感知。
2 实现方法使用SpringSession实现Session并发很简单,如果你的要求不高,只需要一行代码就可以了,在protected void configure(HttpSecurity http)
这个方法里加上.maximumSessions(2)
就OKAY, 这行配置的参数表示服务端最多允许几个客户端帐号同时在线。
完整的代码示例:
主要依赖
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.0.RELEASEversion>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-securityartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redisartifactId>
dependency>
<dependency>
<groupId>org.springframework.sessiongroupId>
<artifactId>spring-session-data-redisartifactId>
dependency>
dependencies>
配置文件
spring:
redis:
host: 256.73.82.27 # 地址,这个ip是瞎写的,第一位是256就不可能的对吧
port: 6379 # 端口
database: 1 # 数据库索引
password: redis
session:
store-type: redis
SpringSecurity配置类
/**
* 这个Bean的作业是在登出时,进行一个发布,具体做了什么还不是很清楚
* 如果没有该Bean,现象是如果配置了http.maxSessionsPreventsLogin(true),当用户登陆数量后,即使进行登出 *** 作,接下来也还是不能正常登陆。
*/
@Bean
public HttpSessionEventPublisher httpSessionEventPublisher() {
return new HttpSessionEventPublisher();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
/*
* 省力其它配置信息
*/
.sessionManagement()
// 最大session并发数
.maximumSessions(2)
/*
* 省力其它配置信息
*/
3 测试方法
启动服务
-
登陆请求A: 使用curl发起登陆请求
curl -X POST -v -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=testUser' -d 'password=123' 'localhost:8765/hgd11-security-api/login'
请求出参:
-
登陆请求B: 再次使用curl发起登陆请求
curl -X POST -v -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=testUser' -d 'password=123' 'localhost:8765/hgd11-security-api/login'
-
登陆请求C: 再次使用curl发起登陆请求
curl -X POST -v -H 'Content-Type: application/x-www-form-urlencoded' -d 'username=testUser' -d 'password=123' 'localhost:8765/hgd11-security-api/login'
-
业务请求D: 使用登陆请求A时响应的session,请求业务接口
curl -X GET -v 'localhost:8765/hgd11-security-api/test/hello' -H 'Cookie: SESSION=NGJjZjdmYzktYzZiMS00Mjg2LTg4MGMtNDBkMmFmNDFkZTNk'
,发现请求认证失败。
测试过程值得说的几点
- 一定要连接进行后两次请求后,也就是测试顺序的A-B-C后,再使用第一次登陆获取的session做业务请求D,这时才能测试出来session并发的效果来。因为在发生session并发时,SpringSecurity是根据session里最后更新时间来判断驱逐哪个session的。最早的那个更新时间对应的session会被驱逐。如果测试顺序是A-B-D-C-D,这时你期望的是A那次登陆会被驱逐,但实际上A并不会被驱逐,而是请求登陆B那次被驱逐了,因为进行D *** 作后,D session的最后更新时间比B的session要更新。
- 之所以使用curl进行测试,而没有使用postman,是因为postman在请求时会自动带上cookie,也就是说会把sessionID带过去。更详细的情况是这样的,进行登陆请求A时,服务器响应了一个sessionID,这时postman把session放在cookie里;进行登陆请求B时,这次登陆请求全带着sessionID过去,服务器看到有sessionID,就知道是同一个客户端,这时只是会change一下sessionId,不会再创建session了,所以session也就不存在并发了。
- 先不要在多副本的情况下测试
如果不知情,使用postman一直来测试session并发,可能测到死也不明白为什么session并发就是测不出来。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)