进销存系统_实现7天免登陆

Posted 上善若水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进销存系统_实现7天免登陆相关的知识,希望对你有一定的参考价值。

一、实现7天免登陆

1.1、免登录基本原理

  1. 用户认证成功之后调用RemeberMeService根据用户名生成token,由TokenRepository写入到数据库,同时也将token写入到浏览器的cookie中。
  2. 重启服务之后,用户再次登入系统会RememberMeAuthenticationFilter拦截,从cookie中读取token信息,与persistent_logins表匹配判断是否使用记住我功能。最终由UserDetailService查询用户信息。

1.2、免登陆实现核心

  • 创建persistent_logins表
DROP TABLE IF EXISTS `persistent_logins`;
CREATE TABLE `persistent_logins`  (
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `series` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `token` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `last_used` timestamp(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
  PRIMARY KEY (`series`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
  • 配置SecurityConfig
package com.xbmu.admin.config.security;

import com.xbmu.admin.filter.CaptchaCodeFilter;
import com.xbmu.admin.pojo.User;
import com.xbmu.admin.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.annotation.Resource;
import javax.sql.DataSource;

/**
 * SpringSecurity配置类
 * @author bitaotao
 * @since 2021-09-12
 */
@SpringBootConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JxcAuthenticationSuccessHandler jxcAuthenticationSuccessHandler;

    @Autowired
    private JxcAuthenticationFailedHandler jxcAuthenticationFailedHandler;

    @Resource
    private IUserService userService;

    @Resource
    private JxcLogoutSuccessHandler jxcLogoutSuccessHandler;

    @Resource
    private CaptchaCodeFilter captchaCodeFilter;

    @Resource
    private DataSource dataSource;

    /**
     * 放行静态资源
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(
                "/images/**",
                "/css/**",
                "/js/**",
                "/lib/**",
                "/error/**");
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // 禁用csrf
        http.csrf().disable()
                .addFilterBefore(captchaCodeFilter, UsernamePasswordAuthenticationFilter.class)
                // 允许frame 页面嵌套
                .headers().frameOptions().disable()
                .and()
                    .formLogin()
                    .usernameParameter("userName")
                    .passwordParameter("passWord")
                    .loginPage("/index")
                    .loginProcessingUrl("/login")
                    .successHandler(jxcAuthenticationSuccessHandler)
                    .failureHandler(jxcAuthenticationFailedHandler)
                .and()
                    .logout()
                    .logoutUrl("/signout")
                    .deleteCookies("JSESSIONID")
                    .logoutSuccessHandler(jxcLogoutSuccessHandler)
                .and()
                    .rememberMe()
                    .rememberMeParameter("rememberMe")
                    // 保存在浏览器端的cookie的名称,如果不设置,默认也是remember-me。
                    .rememberMeCookieName("remember-me-cookie")
                    // 设置token的有效期,即多长时间内可以免除重复登录,单位是秒。
                    .tokenValiditySeconds(7 * 24 * 60 * 60)
                    // 自定义
                    .tokenRepository(persistentTokenRepository())
                .and()
                    .authorizeRequests().antMatchers("/index","/login","/image").permitAll()
                    .anyRequest().authenticated();

    }

    /**
     * 配置从数据库中获取token
     * @return
     */
    private PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        return tokenRepository;
    }

    @Bean
    protected UserDetailsService userDetailsService() {
        return new UserDetailsService() {
            @Override
            public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
                // 根据用户名查询用户记录
                User userDetails = userService.findUserByUserName(userName);
                return userDetails;
            }
        };
    }

    /**
     * 配置 SpringSecurity 密码加密 Bean对象
     * @return
     */
    @Bean
    public PasswordEncoder encoder(){
        return new BCryptPasswordEncoder();
    }

    /**
     * 配置认证Service接口与密码加密实现类
     * @param auth
     * @throws Exception
     */
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService()).passwordEncoder(encoder());
    }
}
  • index.js

1.3、测试


关闭浏览器或重启应用后,重新访问:http://127.0.0.1:8989/main 主页面,是不需要再登录的。

以上是关于进销存系统_实现7天免登陆的主要内容,如果未能解决你的问题,请参考以下文章

用户登录之7天免登陆(垃圾回收机制)

利用Session实现三天免登陆

肖sir___scm进销存管理系统__项目整理

七天免登陆

进销存系统_用户角色分配(12)

Eclipse+Java+Swing+Mysql实现进销存管理系统建议收藏