SpringSecurity实现自动登录功能

SpringSecurity实现自动登录功能

我们知道很多网站都有下次自动登录的功能,springsecurity作为较获得安全技术肯定是也有的

自动登录功能就是,用户在登录成功后,在某一段时间内,如果用户关闭了浏览器并重新打开,或者服务器重启了,都不需要用户重新登录了,用户依然可以直接访问接口数据

要实现记住我这个功能,其实只需要其实只需要在 Spring Security 的配置中,添加如下代码即可

    @Override
    protected void configure(HttpSecurity http) throws Exception{
        http.authorizeRequests()
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .and()
                .rememberMe()
                .key("cphsw")
                .and()
                .csrf().disable();
    }

这里只需要添加一个 .rememberMe() 即可,自动登录功能就成功添加进来了。
我们再写一个测试接口

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
}

重启项目,我们访问 hello 接口,此时会自动跳转到登录页面:
SpringSecurity实现自动登录功能_第1张图片
默认的登录页面多了一个选项,就是记住我。我们输入用户名密码,并且勾选上记住我这个框,然后点击登录按钮执行登录操作
SpringSecurity实现自动登录功能_第2张图片
可以看到,登录数据中,除了 username 和 password 之外,还有一个 remember-me

登录成功之后,就会自动跳转到 hello 接口了。我们注意,系统访问 hello 接口的时候,携带的 cookie
SpringSecurity实现自动登录功能_第3张图片
接下来,我们关闭浏览器,再重新打开浏览器。正常情况下,浏览器关闭再重新打开,如果需要再次访问 hello 接口,就需要我们重新登录了。但是此时,我们再去访问 hello 接口,发现不用重新登录了,直接就能访问到,这就说明我们的 RememberMe 配置生效了

我们来分析一下 cookie 中多出来的这个 remember-me,这个值一看就是一个 Base64 转码后的字符串,我们可以使用网上的一些在线工具来解码,也可以自己写代码来解码

 @Test
    void contextLoads() throws UnsupportedEncodingException {
        String s = new String(Base64.getDecoder().decode("Y3Boc3c6MTU4OTM1NjA0MTU4MzplNjgyMmNhOGZhZjE1YjQ3N2JmNDBkNDQ1NWQzYzZkYg"), "UTF-8");
        System.out.println("s = " + s);
    }

执行这段代码,输出结果如下:
在这里插入图片描述
1.第一段是用户名。
2.第二段看起来是一个时间戳,我们通过在线工具或者 Java 代码解析后发现,这是一个两周后的数据。
3.第三段是使用 MD5 散列函数算出来的值,他的明文格式是 username + “:” + tokenExpiryTime + “:” + password + “:” + key,最后的 key 是一个散列盐值,可以用来防治令牌被修改。
这个key建议自己配置下,要不然默认的是一段UUID,如果服务端重启每次登录时都不一样,导致之前派发出去的所有 remember-me 自动登录令牌失效,配置如下
SpringSecurity实现自动登录功能_第4张图片
在浏览器关闭后,并重新打开之后,用户再去访问 hello 接口,此时会携带着 cookie 中的 remember-me 到服务端,服务到拿到值之后,可以方便的计算出用户名和过期时间,再根据用户名查询到用户密码,然后通过 MD5 散列函数计算出散列值,再将计算出的散列值和浏览器传递来的散列值进行对比,就能确认这个令牌是否有效。

你可能感兴趣的:(SpringSecurity实现自动登录功能)