一、背景
在有些场景下,我们需要限制同一用户的登录数量限制。
比如有些重要的账号,同一时刻只能有登录一次。
再比如类似爱奇艺的会员制,同一时刻只能登录5次。
此文对于登录的限制,采取的做法是:若发现同一用户登录了两次,则后者会将前者的 session 剔除,即要求前者再次登录。(有些场景下的限制是限制后者无法登录,本文暂不介绍)
</p>
二、实现
本文介绍的是基于 SpringSecurity 的一套实现逻辑,个人实现部分比较简单,底层实现交由框架处理了。
本文介绍的是基于 SpringBoot 的注解式配置,xml 版本的配置大同小异。
① 配置
最重要的是下面代码的最后一行配置,设置 maximumSessions(2) 的值为2,代表同一个用户最大能同时登录2次,调整为1则代表同时只能登录一次。
1 | /** |
② 用户实体类的改造
我们自定义了一个实体类 public class StaffProfile implements Serializable, UserDetails{ }
注意,UserDetails 来自如下包:org.springframework.security.core.userdetails.UserDetails;
关键点是实体类需要重写如下三个方法:toString、hashCode、equals,
原有下文介绍,代码如下:
1 | @Override |
三、源码解析
此文所说的控制用户的登录数,实现方式其实就是控制同一用户创建的 session 数,达到阀值,则剔除最早的 session。
关键代码是 org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy 类下的方法:onAuthentication()
大致流程是,当按照上文所述设置了maximumSessions()之后,所有的请求都会走这个方法,这个方法会先获取该用户建立的所有 session,如果已建立的 session数量大于预设值,则会删除最早建立的 session;