Spring Security实现两周内自动登录"记住我"功能
作者:字母哥博客 发布时间:2021-12-15 17:59:22
本文是Spring Security系列中的一篇。在上一篇文章中,我们通过实现UserDetailsService和UserDetails接口,实现了动态的从数据库加载用户、角色、权限相关信息,从而实现了登录及授权相关的功能。这一节就在此基础上新增,登录过程中经常使用的“记住我”功能,也就是我们经常会在各种网站登陆时见到的"两周内免登录",“三天内免登录”的功能。该功能的作用就是:当我们登录成功之后,一定的周期内当我们再次访问该网站,不需要重新登录。
一、最简实践
其实实现这个功能非常简单,只需要我们在重写WebSecurityConfigurerAdapter 方法配置HttpSecurity 的时候增加rememberMe()方法。(下面代码中省略了大量的关于Spring Security登录验证的配置,在本号此前的文章中已经讲过)
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.rememberMe(); //实现记住我自动登录配置,核心的代码只有这一行
}
}
然后在登录表单中加入一个checkbox勾选框,name属性的值目前必须是“remember-me”(个性化更改的方法后面会讲)。
<label><input type="checkbox" name="remember-me"/>自动登录</label>
就是这么简单,我们就实现了记住我功能,默认效果是:2周内免登录。
二、实现原理
很多朋友可能看了上面的实现过程心里都犯懵,这样就实现了?下面和大家说明一下这过程中间,都做了哪些事情。
当我们登陆的时候,除了用户名、密码,我们还可以勾选remember-me。
如果我们勾选了remember-me,当我们登录成功之后服务端会生成一个Cookie返回给浏览器,这个Cookie的名字默认是remember-me;值是一个token令牌。
当我们在有效期内再次访问应用时,经过RememberMeAuthenticationFilter,读取Cookie中的token进行验证。验正通过不需要再次登录就可以进行应用访问。
这个token令牌是一个 MD5 hash字符串:包含username、expirationTime和passwod和一个预定义的key,并将他们经过MD5加密。可能有的朋友会问:这样安全么?如果cookie被劫持,一定是不安全的,别人拿到了这个字符串在有效期内就可以访问你的应用。这就和你的钥匙token被盗了,你家肯定不安全是一个道理。 但是不存在密码被破解为明文的可能性,MD5 hash是不可逆的。
RememberMeAuthenticationFilter在Spring Security过滤器链中处于整体偏后的位置,所以只有当各种传统的登录方式都无法完成验证的情况下,才走RememberMeAuthenticationFilter,这也是符合实际需求的。
三、个性化配置
在实际的开发过程中,我们还可以根据需求做一些个性化的设置,如下:
.rememberMe()
.rememberMeParameter("remember-me-new")
.rememberMeCookieName("remember-me-cookie")
.tokenValiditySeconds(2 * 24 * 60 * 60);
tokenValiditySeconds用于设置token的有效期,即多长时间内可以免除重复登录,单位是秒。不修改配置情况下默认是2周。
通过rememberMeParameter设置from表单“自动登录”勾选框的参数名称。如果这里改了,from表单中checkbox的name属性要对应的更改。如果不设置默认是remember-me。
rememberMeCookieName设置了保存在浏览器端的cookie的名称,如果不设置默认也是remember-me。如下图中查看浏览器的cookie。
四、token数据库存储方式
上面我们讲的方式,就是最简单的实现“记住我-自动登录”功能的方式。这种方式的缺点在于:token与用户的对应关系是在内存中存储的,当我们重启应用之后所有的token都将消失,即:所有的用户必须重新登陆。为此,Spring Security还给我们提供了一种将token存储到数据库中的方式,重启应用也不受影响。
有的文章说使用数据库存储方式是因为这种方式更安全,笔者不这么认为。虽然数据库存储的token的确不再是用户名、密码MD5加密字符串了,而是一个随机序列号。但是一旦你的随机序列号cookie被劫持,效果是一样的。好比你家有把密码锁:你把钥匙丢了和你把密码丢了,危害性是一样的。
上图是token数据库存储方式的实现原理和验证过程,下面我们就来实现一下。首先,我们需要键一张数据库表persistent_logins:
CREATE TABLE `persistent_logins` (
`username` varchar(64) NOT NULL,
`series` varchar(64) NOT NULL,
`token` varchar(64) NOT NULL,
`last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`series`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
初始化一个PersistentTokenRepository类型的Spring bean,并将系统使用的DataSource注入到该bean中。(当然前提一定是你已经在Spring Boot的application.yml中配置好DataSource相关的连接属性,这里不再赘述)
@Autowired
private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository(){
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
最后在Spring Security配置方法configure(HttpSecurity http)加上如下的个性化配置:
.rememberMe()
.tokenRepository(persistentTokenRepository())
总结
以上所述是小编给大家介绍的Spring Security实现两周内自动登录"记住我"功能网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
来源:https://www.cnblogs.com/zimug/archive/2019/11/28/11949330.html
猜你喜欢
- Memento定义:memento是一个保存另外一个对象内部状态拷贝的对象,这样以后就可以将该对象恢复到原先保存的状态。Memento模式相
- 冒泡排序:就是按索引逐次比较相邻的两个元素,如果大于/小于(取决于需要升序排还是降序排),则置换,否则不做改变这样一轮下来,比较了n-1次,
- 一个比较常见的改进用户体验的方案是用Redo/Undo来取代确认对话框,由于这个功能比较常用,本文简单的给了一个在C#中通过Command模
- 什么是mybatis,mybatis有什么特点,下面先给大家介绍下mybatis的概念及特点。jdbc开发优缺点:1)优点:简单易学,上手快
- 委托:顾名思义,让别人帮你办件事。委托是C#实现回调函数的一种机制。可能有人会问了,回调函数是个啥???举个例子:我现在是一家公司的老板,公
- 一个线程如何知道另一线程已经结束?Thread类提供了回答此问题的方法。有两种方法可以判定一个线程是否结束。第一,可以在线程中调用isAli
- 线程间通信:由于多线程共享地址空间和数据空间,所以多个线程间的通信是一个线程的数据可以直接提供给其他线程使用,而不必通过操作系统(也就是内核
- Java IO中File的使用是比较频繁的,在文件的上传和删除中都会用到的。比如我们在写管理系统的时候有可能会用到图片的上传,和删除。那么我
- 在前后端分离的项目中后端返回的格式一定要友好,不然会对前端的开发人员带来很多的工作量。那么SpringBoot如何做到统一的后端返回格式呢?
- 发现问题肯定有人发现连接mysql失败,然后又找不到问题所在,又出现一大最报错,如下图。解决过程 1.先查询自己的java版本,在
- 1、数组理论基础数组是存放在连续内存空间上的相同类型数据的集合,可以通过下标索引的方式获取到下标下对应的数据。举个栗子(字符数组)~可以看到
- 我已经很精简了,两篇(Spring Boot启动过程(一)、spring Boot启动过程(二))依然没写完,接着来。refreshCont
- 需求当游戏显示3d场景及其UI的时候。玩家左右晃动手机的时候,UI界面会随之左右偏移。上下晃动的时候,3D场景会随之上下偏移。手机停止晃动的
- 一、概述使用Java技术构建Web应用时, 我们通常离不开tomcat和jetty之类的servlet容器,这些Web服务器功能强大,性能强
- 1.委托delegate委托delegate也是一种类型,在任何可以声明类的地方都可以声明委托,它将方法当做另一个方法的参数进行传递,这样就
- 每一个应用程序,其实都会有分享的需求,比如一键分享一篇文章或者一些活动到微博或者微信亦或者是twitter等社交平台,因为人类是社交动物,而
- 一、堆排序1、什么是堆排序(1)堆排序:堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆积是一个近似完全二叉树的结构
- 创建Avalonia的MVVM项目,命名DragDemo ,然后将项目的Nuget包更新到预览版<ItemGroup>
- IntelliJ IDEA是很多程序员必备且在业界被公认为最好的Java开发工具,有很多小伙伴在安装完IDEA并且tomcat之后,启动to
- 前一段时间,在做摄像头拍照上传,摄像头拍的照片为base64编码格式的字符串,需要上传至项目中,则需要使用到将base64编码字符串转换为图