在大多数网站中,都会实现RememberMe这个功能,方便用户在下一次登录时直接登录,避免再次输入用户名以及密码去登录,下面,主要讲解如何使用Spring Security实现记住我这个功能以及深入源码探究它的原理。
首先,如下图所示为Spring Security实现RememberMe功能的原理图:
先来看看RememberMeService接口的3个方法
| 方法名 | 执行时间 | 描述 |
|---|---|---|
| autoLogin | 收到请求时,由RememberMeAuthenticationFilter调用执行 | 实现免密登录 |
| loginFail | 认证失败时被执行 | 清除remember-mecookie等 |
| loginSuccess | 认证成功时被执行 | 创建Token,持久化Token到内存或数据库 |
SpringSecurity中的一个很重要的过滤器AbstractAuthenticationProcessingFilter,它是认证过程的入口也是出口。看一下源码:
剥开successfulAuthentication()方法看看:
在用户认证成功后,即要对remember-me功能的处理啦。
remberMeServies.loginSuccess()就是这一切的开端!!
看看这个service的实现类:
- 这个NullRememberMeService很奇特,查看this.rememberMeService属性发现默认的实现类就是这个NullRememberMeService。
- 但实际上这个实现类就和它的名字一样没有丝毫作用。
- 重点在另一个AbstractRememberMeServices实现类中:
- 出现了两个子类:
- PersistentTokenbasedRememberMeServices:
- 实现持久化Token RememberMeService
- TokenbasedRemeberMeService
- 基础Token RememberMeService
- PersistentTokenbasedRememberMeServices:
又是两个实现类:
- InMemoryTokenRepositoryImpl
- 在内存中存储Token的实现类,内部维护了一个Map存储Token
- JdbcTokenRepositoryImpl
- 在数据库中存储Token的实现类。内部已经存好了操作Token的CURD,使用JdbcTemplate进行操作数据库。tip:使用的时候一定会需要到数据源的设置
这下两种Token的存储方式就已经裸露的出来,总结一下两种存储方式的特点:
- 基于数据库持久化Token,
- 在内存中使用Map维护了Token。
前面在认证成功后就会创建Token,只需要传入remember-me参数,就可以持久化Token。以便下一次的免密登录。
免密登录要从RememberMeAuthenticationFilter过滤器开始:



