原创首发
SpringSecurity跟SpringBoot的整合-remember me

SpringSecurity跟SpringBoot的整合-remember me
系列文章
前面我们已经学习了
SpringSecurity跟SpringBoot的整合-项目创建
SpringSecurity跟SpringBoot的整合-自定义登录页面
SpringSecurity跟SpringBoot的整合-从数据库中读取用户信息校验
接下来我们看看remember me这个功能
在哪里判断是否需要记住呢?
在AbstractRememberMeServices这个类里
public final void loginSuccess(HttpServletRequest request,
HttpServletResponse response,
Authentication successfulAuthentication) {
if (!this.rememberMeRequested(request, this.parameter)) {
this.logger.debug("Remember-me login not requested.");
} else {
this.onLoginSuccess(request, response, successfulAuthentication);
}
}
这里有个判断,是否要记住对吧!
点进去看看。
判断是否需要记住的代码在这
protected boolean rememberMeRequested(HttpServletRequest request, String parameter) {
if (this.alwaysRemember) {
return true;
} else {
String paramValue = request.getParameter(parameter);
if (paramValue != null && (paramValue.equalsIgnoreCase("true")
|| paramValue.equalsIgnoreCase("on")
|| paramValue.equalsIgnoreCase("yes")
|| paramValue.equals("1"))) {
return true;
} else {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Did not send remember-me cookie (principal did not set parameter '"
+ parameter + "')");
}
return false;
}
}
}
key是这个
private String parameter = "remember-me";
所以,我们在前端,通过一个remenber-me的checkbox,或者任意吧,只要值是
true,或者on,或者yes,或者1都行,都会返回true。
如何记住呢?
protected abstract void onLoginSuccess(HttpServletRequest var1,
HttpServletResponse var2, Authentication var3);
这是一个抽象方法,所以由子类去实现
我们打开PersistentTokenBasedRememberMeServices
把token保存到了cookies里了
protected void onLoginSuccess(HttpServletRequest request,
HttpServletResponse response, Authentication successfulAuthentication) {
String username = successfulAuthentication.getName();
this.logger.debug("Creating new persistent login for user " + username);
PersistentRememberMeToken persistentToken = new PersistentRememberMeToken(username,
this.generateSeriesData(),
this.generateTokenData(), new Date());
try {
this.tokenRepository.createNewToken(persistentToken);
this.addCookie(persistentToken, request, response);
} catch (Exception var7) {
this.logger.error("Failed to save persistent token ", var7);
}
}
所以,开启remember me这个功能,两个步骤
- 前端提交一个选项,key是remember-me,value可以有很多种,可以是true,可以是1,可以是on,可以是yes
- 后端开启这个功能
配置remember me
- 前端添加这个一项
<div class="login-box">
<div class="login-title">
XXX管理系统登录
</div>
<div class="login-content-part">
<form action="/login" method="post">
账号:<input type="text" name="sob_username" placeholder="请输入账号">
<br>
密码:<input type="password" name="sob_password" placeholder="请输入密码">
<br>
记住我:<input type="checkbox" name="remember-me" value="true">
<input type="submit" value="登录">
</form>
</div>
</div>
这里相碰的style我就不粘贴出来了,看前面的吧,前面应该有给出的。
- 开启remember me
http //开启remember me
.rememberMe()
//设置token的过期时间,单位为:秒
.tokenValiditySeconds(3600)
//处理自定登录的service
.userDetailsService(userService);
测试登录
查看一下cookies
我们设置的是一个小时过期,所以一个小时内,关掉,打开浏览器,还是会自动登录的。
但是这样子做并不安全
我们应该把token信息保存到数据库里,然后再算出一个key,保存到cookies里
而这些工作,spring security 已经完成了,我们只要配置一下数据库就好了
配置数据库
- 创建数据库
CREATE TABLE persistent_logins (
username VARCHAR(64) NOT NULL,
series VARCHAR(64) PRIMARY KEY,
token VARCHAR(64) NOT NULL,
last_used TIMESTAMP NOT NULL
)
在配置文件中加入
@Bean
public PersistentTokenRepository persistentTokenRepository() {
JdbcTokenRepositoryImpl persistentTokenRepository = new JdbcTokenRepositoryImpl();
persistentTokenRepository.setDataSource(dataSource);
return persistentTokenRepository;
}
修改一下remember me的配置
http //开启remember me
.rememberMe()
//设置token的过期时间,单位为:秒
.tokenValiditySeconds(3600)
.tokenRepository(persistentTokenRepository())
//处理自定登录的service
.userDetailsService(userService);
登录验证
我们会发现,在数据库里多了一条记录的
浏览器也能看到我们的cookies了
到此,rememeber me就介绍完了。