SpringBoot整合SpringSecurity登入-记住我

记住我功能,这个是登入时常见的功能,就是用户在登入一次以后,勾选记住我功能按钮后,系统会记住用户一段时间,在这段时间内用户不应反复登入系统的操作;
在这里插入图片描述
简单说明一下:浏览器在用户登入的时候,发送认证请求给UsernamePassworAuthenticationFilter这个身份认证过滤器,或者是自己特定的过滤器,当我们的认证过滤器认证成功后会调用一个RemeberMeService的服务,这个服务里面有一个TokenRepository,这个会生成一个Token,然后将这个Token返回给浏览器并写入到Cookie里面,同时会将Token写入到数据库里面,这里Token和用户名是一一对应的,当我们的用户过了几天后在来请求我们的服务器,那么他就不需要登入了,在有效时间内可以直接访问受保护的服务,那么这些请求在经过过滤器链的时候会经过一个RememberMeAuthenticationFilter,这个过滤器的作用就是获取Cookie中的token,然后交给RemeberMeService,然后由RokenRepository到数据库中查询这个token在数据库中有没有记录,数据库中有token记录将对应的用户名取出来,取出用户名后会调用UserDetailsService,然后获取用户的信息放到SecurityContenx里面存储,然后用户就自动登入上,这就是记住我功能的基本流程!

RememberMeAuthenticationFilter
在这里插入图片描述
RememberMeAuthenticationFilter是位于过滤器里面的倒数第二个的位置上,前面是一些其他的认证过滤器,当其他的认证过滤器都无法认证用户信息的时候,RememberMeAuthorizationFilter会尝试做认证的操作!
记住我的原理差不多就是这样的!下面来具体实现!

在SpringSecurity配置类中注入数据源和UserDetailsService,数据源是用来插入、更新token等操作的,UserDetailsService是用来查出用户名后校验用户身份的操作,然后在添加Token持久化存储的Bean,在重写的configure方法中添加对应配置即可

服务端代码

 @Autowired
    private DataSource dataSource;//注入数据源

    @Autowired
    private UserDetailsService userDetailsService;//这里实际上就是将用户名取出来交给userDetailsService的操作

    @Bean//Token持久化存储
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl tokenRepository=new JdbcTokenRepositoryImpl();//这个接口完成建表,查询,修改等操作
        //public static final String CREATE_TABLE_SQL = "create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, "
        //			+ "token varchar(64) not null, last_used timestamp not null)";
        tokenRepository.setDataSource(dataSource);
        tokenRepository.setCreateTableOnStartup(false);//启动的时候会自动建表--但是这里没有表已存在不建表的操作,所以表存在后不能再次开启
        return tokenRepository;

    }

@Override
    protected void configure(HttpSecurity http) throws Exception {
       .formLogin()//这是开启表单登入的意思
       		.xxx
       		.xxx
       		.xxx
       		.and()
       //记住我的配置核心
       .rememberMe()//记住我功能开启
        	.tokenRepository(persistentTokenRepository())
        	.tokenValiditySeconds(毫秒数)//记住我的时间--token的过期时间
        	.userDetailsService(userDetailsService)//最终拿到用户名后用userDetailsService去登入
        	.and()

    }

表单界面代码

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
	<h2>标准登录页面</h2>
	<h3>表单登录</h3>
	<form action="/authentication/form" method="post">
		<table>
			<tr>
				<td>用户名:</td>
				<td><input type="text" name="username"></td>
			</tr>
			<tr>
				<td>密码:</td>
				<td><input type="password" name="password"></td>
			</tr>
			<tr>
				<td>图形验证码:</td>
				<td>
					<input type="text" name="imageCode">
					<img src="/code/image?width=200">
				</td>
			</tr>
			<tr>
				<td colspan='2'><input name="remember-me" type="checkbox" value="true" />记住我</td>
			</tr>
			<tr>
				<td colspan="2"><button type="submit">登录</button></td>
			</tr>
		</table>
	</form>
</body>
</html>

版权声明:本文为CSDN877425287原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。