RememberMe基本用法
我们先来看一种最简单的用法。
首先创建一个 Spring Boot 工程,引入 Spring-boot-starter-security 依赖。工程创建成功后,添加一人 HelloController 并创建一人测试接口,代码如下:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "hello";
}
}
然后创建 SecurityConfig 配置文件:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
PasswordEncoder passwordEncoder() {
return NoOpPasswordEncoder.getInstance();
}
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("javaboy")
.password("123")
.roles("admin");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.rememberMe()
.key("javaboy")
.and()
.csrf().disable();
}
}
这里我们主要是调用了HttpSecurity 中的 rememberMe 方法并配置了一个 key(key 在这里很重要——它是整个应用程序的私有秘钥,将在生成令牌的内容时使用),该方法最终会向过滤器链中添加 RememberMeAuthenticationFilter 过滤器。
配置完成后,启动项目,当我们访问 /hello 接口时,会自动重定向到登录页面,如图6-2 所示。

可以看到,此时的默认登录页面多了一个 RememberMe 选项,勾选上 RememberMe,登录成功之后,我们就可以访问 /hello 接口了。访问完成后,关闭浏览器再重新打开,此时不需要登录就可以直接访问 /hello 接口;同时,如果关闭掉服务端重新打开,再去访问 /hello 接口,发现此时也不需要登录了。
那么这一切是怎么实现的呢?打开浏览器控制台,我们来分析整个登录过程。
首先,当我们单击登录按钮时,多了一个请求参数 remember-me,如图6-3所示。

很明显,remember-me 参数就是用来告诉服务端是否开启 RememberMe 功能,如果开发者自定义登录页面,那么默认情况下,是否开启 RememberMe 的参数就是remember-me。
当请求成功后,在响应头中多出了一个 Set-Cookie,如图6-4所示。

在响应头中给出了一个 remember-me 字符串。以后所有请求的请求头 Cookie 字段,都会自动携带上这个令牌,服务端利用该令牌可以校验用户身份是否合法。
大致的流程就是这样,但是大家发现这种方式安全隐患很大,一旦 remember-me 令牌泄漏,恶意用户就可以掌看这入令牌去随意访问系统资源。持久化令牌和二次校验可以在一定程度上降低该问题带来的风险。