1. 程式人生 > >spring-Security(三):記住我,實現下次免登入

spring-Security(三):記住我,實現下次免登入

記住我基本原理

  1. 使用者認證成功之後呼叫RemeberMeService根據使用者名稱名生成TokenTokenRepository寫入到資料庫,同時也將Token寫入到瀏覽器的Cookie
  2. 重啟服務之後,使用者再次登入系統會由RememberMeAuthenticationFilter攔截,從Cookie中讀取Token資訊,與persistent_logins表匹配判斷是否使用記住我功能。最中由UserDetailsService查詢使用者資訊

具體實現:

步驟一:

建立persistent_logins

createtable persistent_logins (username varchar

(64) notnull, series varchar(64) primary key, token varchar(64) notnull, last_used timestampnotnull);

這個表是統一的,springsecrity會自動在這個表儲存和讀取token資訊

步驟二:

登陸頁面新增記住我複選款(name必須是remeber-me)

<input name="remember-me" type="checkbox"> 下次自動登入

步驟三:配置WebSecurityConfig

1.加入下面的程式碼,springSecurity會根據情況自動將token插入persistent_logins表

和和從persistent_logins表讀取token

 @Autowired
    private DataSource dataSource;
    @Bean
    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        return tokenRepository;
    }
2.設定httpSecurity
 protected void configure(HttpSecurity http) throws Exception {
        http
                .authorizeRequests()
                .antMatchers("/").permitAll()
                .antMatchers("/user/**").hasRole("USER")
                .antMatchers("/ws").hasRole("USER")
                .and()
                .formLogin().loginPage("/login").defaultSuccessUrl("/ws")
                .and()
                .logout().logoutUrl("/logout").logoutSuccessUrl("/login")

                //記住我開始,場景:有這樣一個場景——有個使用者初訪並登入了你的網站,
                // 然而第二天他又來了,卻必須再次登入。於是就有了“記住我”這樣的功能來方便使用者使用
                .and()
                .rememberMe()
                .tokenRepository(persistentTokenRepository())//設定操作表的Repository
                .tokenValiditySeconds(60 * 60 * 24 * 7)//設定記住我的時間為7天
                .userDetailsService(myUserDetailsService);//設定userDetailsService
                //記住我結束
        
        // 加http.csrf().disable()是為了防止報這個錯Whitelabel Error Page
       //This application has no explicit mapping for /error, so you are seeing this as a fallback.
        http.csrf().disable();

    }