zoukankan      html  css  js  c++  java
  • spring security实现记住我下次自动登录功能

    spring security实现记住我下次自动登录功能

    上一篇: spring security的BCryptPasswordEncoder加密和对密码验证的原理

    一、原理分析

    第一次登陆时,如果用户勾选了readme选项,登陆成功后springsecurity会生成一个cookie返回给浏览器端,浏览器下次访问时如果携带了这个cookie,springsecurity就会放行这次访问。

    二、实现方式

    2.1 简单实现方式

    (1) 在springsecurity的配置文件中,http节点下增加一个remember-me配置

    <security:http auto-config="true" use-expressions="false">
            <!-- 配置链接地址,表示任意路径都需要ROLE_USER权限,这里可以配置
             一个逗号隔开的角色列表-->
            <security:intercept-url pattern="/**" access="ROLE_USER"/>
    
            <!--自定义登录页面-->
            <security:form-login login-page="/login.html" login-processing-url="/login"
                                 username-parameter="username" password-parameter="password"
                                 authentication-failure-forward-url="/failed.html"
                                 default-target-url="/index.html"
    
            />
            <!--关闭csrf,默认是开启的-->
            <security:csrf disabled="true"/>
    
            <security:remember-me remember-me-parameter="remembermeParamater" />
            <!-- 退出 -->
            <security:logout invalidate-session="true" logout-url="/logout.do" logout-success-url="/login.html"/>
        </security:http>
    

    其中remember-me-parameter="remembermeParamater"指定前台传递的是否rememberme的参数名,前台要传递的参数值是true或false

    (2)前台登录页面上增加一个checkbox

    <form action="/login" method="post">
            用户名:<input type="text" name="username" placeholder="请输入用户名"><br>
            密 码:<input type="password" name="password" placeholder="请输入密码"><br>
            记住我:<input id="_spring_security_remember_me" type="checkbox" name="remembermeParamater" value="true">
            <input type="submit" value="登录">
        </form>
    

    checkbox的name属性要和上边配置文件中的remember-me-parameter="remembermeParamater"保持一致。

    (3)测试

    启动工程,进行登录,登录成功后观察cookie,会发现服务器端返回了一个名为remember-me的cookie

    现在关闭浏览器,再次打开并访问,只要不清除cookie就可以直接访问资源,不需要重新登录。

    这种方式有个弊端,浏览器端要携带的这个cookie值服务端是存放在内存中的,并没有进行持久化,所以如果服务重启后服务器端存储的这个值就会丢失,浏览器端的rememberme就会失效。为了解决这个问题就需要将服务器端生成的这个cookie值持久化到数据库中。

    2.2 数据库实现方式

    (1)创建一张表用来持久化rememberme的记录

    -- 创建记录rememberme记录的表
    CREATE TABLE persistent_logins
    (
      username  VARCHAR(64),
      series   VARCHAR(64),
      token     VARCHAR(64),
      last_used DATETIME
     );
    

    (2)将spring-security 配置文件中的rememberme标签的内容改为如下内容

    <security:remember-me remember-me-parameter="remembermeParamater" data-source-ref="dataSource"
                                  token-validity-seconds="86400"/>
    

    data-source-ref="dataSource"用来指定数据源,spring-security通过数据源来操作数据库中的persistent_logins表

    token-validity-seconds表示rememberme的有效时间,以秒为单位,这里的86400=24*3600表示一天

    (3)测试

    启动工程,进行登录,登录成功后会在persistent_logins表中生成一条记录,


    关闭浏览器再次访问时会根据浏览器中携带的cookie值来查找数据库中的这条记录,如果查询到了就认证通过

    三、区分是密码登录还是rememberme登录

    在用户进行一些敏感操作时,需要区分是否是rememberme登录,如果是需要让用户跳转到登录页面。

    在congtroller层提供一个方法来进行判断

    @GetMapping("/isRemembermeUser")
    public boolean isRemembermeUser(){
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if(authentication==null){
            return false;
        }
        //判断当前用户是否是通过rememberme登录,是返回true,否返回false
        return RememberMeAuthenticationToken.class.isAssignableFrom(authentication.getClass());
    }
    

    先使用密码登录,访问http://localhost/user/isRemembermeUser.do,后台接口返回false,再关闭浏览器再次访问这个地址,后台接口返回true,表示这次是使用rememberme进行的认证。

    测试工程代码的地址:工程示例

  • 相关阅读:
    AcWing 225. 矩阵幂求和 (矩阵快速幂+分治)打卡
    AcWing 220.最大公约数 欧拉函数打卡
    2019 牛客暑期多校 B generator 1 (矩阵快速幂+倍增)
    2019 牛客暑期多校 G subsequence 1 (dp+组合数)
    LINUX查看文件大小
    TFTP error: 'Only absolute filenames allowed' (2)
    zmediaboard-Hi3518参数及配置
    移植RTL8188CUS USB-WIFI(移植失败)
    如何安裝繁體暴雪應用程式
    MySQL添加用户、删除用户与授权
  • 原文地址:https://www.cnblogs.com/chengxuxiaoyuan/p/11961102.html
Copyright © 2011-2022 走看看