美文网首页
ch07:将Remember Me Token存储到数据库

ch07:将Remember Me Token存储到数据库

作者: 伊娃瓦力 | 来源:发表于2017-07-21 10:56 被阅读0次

    实际运行过ch03的朋友可能发现Remember Me有个缺陷,当我们重启服务器后Remember Me将失效。这是因为用户的session已经丢失了,这对用户来说是非常不方便的。系统其实间接地暴露了自己的运维信息,这是非常不应该的。

    Spring Security提供了Remember Me Toke持久化技术来解决这个问题。RememberMeServices默认实现类是TokenBasedRememberMeServices,该类将Remember Me Token存储到内存,当重启服务后,内存数据丢失,无法验证用户的有效Token。

    PersistentTokenBasedRememberMeServices是RememberMeServices的另一个实现,其通过PersistentTokenRepository将Remember Me Token存储到数据库。当用户再次登入后,通过对比cookie和数据库就可以完成认证过程。

    只需要通过修改WebSecurityConfigurerAdapter即可以使Spring Security启动PersistentTokenBasedRememberMeServices。

     @Override
        protected void configure(HttpSecurity http) throws Exception {
            http
                    .authorizeRequests()
                    .antMatchers("/assets/**").permitAll()
                    .antMatchers("/**").hasRole("USER")
                    .and().formLogin().loginPage("/login.jsp").permitAll().loginProcessingUrl("/login")
                     //自动识别tokenRepository类型,启用PersistentTokenBasedRememberMeServices
                    .and().rememberMe().tokenRepository(persistentTokenRepository())
                    .and().csrf().disable();
        }
    
       /**
         * 可持久化的cookie token服务
         *
         * @return
         */
        @Bean
        public PersistentTokenRepository persistentTokenRepository() {
            JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
            tokenRepository.setDataSource(dataSource);
            return tokenRepository;
        }
    

    创建MySql数据库脚本

    
    -- ----------------------------
    -- Table structure for persistent_logins
    -- ----------------------------
    DROP TABLE IF EXISTS `persistent_logins`;
    CREATE TABLE `persistent_logins` (
      `username` varchar(64) NOT NULL,
      `series` varchar(64) NOT NULL,
      `token` varchar(64) NOT NULL,
      `last_used` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`series`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    SET FOREIGN_KEY_CHECKS=1;
    

    启动服务,登录用户并选择Remember Me。查询数据库,就可以看到persistent_logins表中增加了一条记录。


    Paste_Image.png

    重启浏览器,不用认证直接登录功能正常。
    重启服务器,刷新用户界面,不用认证直接登录功能正常。
    用户友好性大大提高,不需要用户因服务器重启而重新认证。

    PersistentTokenBasedRememberMeServices为每个用户创建一个唯一的series,用户在继续认证和交互时要使用series来查找对应的token,与存储在cookie中的Token进行对比完成认证。series和token都是随机生成的,被暴力破解的难度大大降低。

    代码示例:https://github.com/wexgundam/spring.security/tree/master/ch07

    相关文章

      网友评论

          本文标题:ch07:将Remember Me Token存储到数据库

          本文链接:https://www.haomeiwen.com/subject/gkuskxtx.html