就像登录qq一样,一个手机登录会将另外一个手机挤下线,这个就叫会话管理。
这个东西非常简单,在默认情况下可以登录n多次,一旦开启,就不允许登录多个。
什么是一个会话。
我们简单理解就是一个浏览器的同一个用户算一个用户,比如谷歌,你添加访客登录
打开的新窗口就是另一个会话
不同浏览器之间也是不同的会话。
我们只需要简单的配置一下,就可以实现,这边登录,那边下线的效果。
在security的执行链中添加以下配置
我们设置最大的并发数为1,也就是一个用户只可以在一台设备上登录
注:这里有人会在加了这个后
出现报红,怎么办呢,再加一个and()
这里只要看到and的返回值是httpsecurity就好了,是的话就不用继续,不是就继续加一个。
这个地方解释一下为什么会出现俩个and的情况。
如图,在这个层级还可以配置一些会话的其他策略,比如:超过了一个了怎么办,是把上一个踢掉还是怎么办,就是说这个会话策略里还有其他配置,你目前处于这个层级,是会话配置的层级。当你and()以后,你会回到选择到和会话同一级地方,
同样的,回到这一级又可以配其他策略,比如session的策略,就是在这一级。
可以把这个链看成一个菜单.sessionManagement()让你菜单进去了一层,.maximumSessions(1)
又让你进去了一层,此时返回就需要两次,也就是两个and。
在服务器,Spring Security维护了一个会话注册表,所有的登录上来的用户,都会注册到这个注册表中,本质上是一个map集合,key是用户对象,value保存了用户所有的会话对象,Map<User,List<Session>>。
当用户注销登录时,用户的session会被字段销毁,但是在map中的session不会自动移除,所以当用户注销时,将List的集合中的用户的对应会话移除掉。
这个也很简单,只需要在spring容器中注册一个Bean就可以了。
到了这个位置,就会有人会出现一个问题,设置的会话怎么看都没起作用,设置了最大会话为1,其他会话一样可以登录,且一起的也没退出。这是为什么?
我们回到这个map里Map<User,List<Session>>,map的key是当前的用户对象,用对象做map的key一般来说需要重写equals和hashcode方法,不然每次登录上来,User对象都是现场new出来的,可不就出问题了吗。
我们重写一下User的方法
用户名已经是唯一的了,我这里就只选用户名,一直next,结束。
重启一下,看看效果。
此时所有的配置都生效了。