暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

SpringSecurity记住我

魏卯卯 2019-12-09
277

强迫学习的东西是不会保存在心里的。

—《柏拉图论教育》


实现“记住我”功能:

    记住我基本原理

    记住我功能具体实现


    用户在登录以后,系统会记住此用户一段时间,在这段时间内用户不用反复登录就可以使用我们的系统。


记住我基本原理

   1、浏览器在发送用户请求的时候,会到UsernamePasswordAuthenticationFiter,当这个过滤器认证成功之后会调用RemeberMeService服务。
   2、RemeberMeService会生成一个token,并把这个token写入到浏览器的cookie里面同时会用TokenRepository把token存入到数据库中。因为是认证成功之后进行存库操作,所以SpringSecurity会把用户名也写入库中,用户名与token是一一对应的。
 3、过了一天之后再访问我们的系统请求时会经过一个RememberMeAuthenticationFilter过滤器,这个过滤器的作用就是读取Cookie中的token交给RememberMeService,然后RememberMeService会根据token去数据库中查数据库中是否有记录,有记录则把用户名取出来然后调用UserDetailsServicer把用户名放入SecurityContext然后就登录成功啦。
RememberMeAuthenticationFilter位置:

    当前面的Filter都没有办法认证用户信息时就会用RememberMeAuthenticationFilter尝试进行认证。


记住我功能具体实现
首先编写页面:

在登录页面添加记住我 选项,其中记住我的选择框必须是input checkbox类型的多选框,并且它的name必须是name="remember-me"

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<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 colspan='2'>
<span style="display: none;">name remember-me 是固定的</span>
<input name="remember-me" type="checkbox" value="true" />
<span>记住我</span>
</td>
</tr>
<tr>
<td colspan="2"><button type="submit">登录</button></td>
</tr>
</table>
</form>
</body>
</html>
复制

config配置:

    首先我们来配置一下TokenRepository。

    @Autowired
    private DataSource dataSource;
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
return tokenRepository;
}
复制

我们点击进入JdbcTokenRepositoryImpl 看一下:

这里面有一个CREATE_TABLE_SQL的变量,因为它要把token存入到数据库中所以要创建一个表,这个脚本可以拿到数据库中执行也可以设置参数:

 @Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
tokenRepository.setDataSource(dataSource);
//在启动的时候创建表 如果数据库有该表,再设置为true,启动会报错
        tokenRepository.setCreateTableOnStartup(true);
return tokenRepository;
}
复制

然后我们SpringSecurity:

    @Override
protected void configure(HttpSecurity http) throws Exception {
http
.formLogin()//表单登录的方式
//自定义成功处理器
.successHandler(myAuthenticationSuccessHandler)
//自定义失败处理器
.failureHandler(myAuthenticationFailureHandler)
.and()
                 //以下是rememberMe的配置
.rememberMe()
.tokenRepository(persistentTokenRepository())//设置tokenRepository
.tokenValiditySeconds(3600)//token过期秒数,一般是一周或者两周
.userDetailsService(myUserDetailService)//指定userDetails用来登陆
.and()
.authorizeRequests()//要授权请求的意思
.antMatchers("/login.html").permitAll()//配置不拦截登陆页面
.anyRequest()//任何的请求
.authenticated()//都需要身份认证
.and()
.csrf().disable();//关掉跨站请求伪造的防护
}
复制

此时SpringSecurity的记住我功能已经实现了!

我们勾选记住我登录后查看数据库会出现一个表和数据:

然后我们重启系统后,再次请求会发现无需登录。


文章转载自魏卯卯,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论