redis+springsecurity+mybtais-plus+JWT

redis+springsecurity+mybtais-plus+JWT

01 引入依赖

xml 复制代码
       
		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
<!--lombok依赖-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--    使用knife4j依赖 -->
        <dependency>
            <groupId>com.github.xiaoymin</groupId>
            <artifactId>knife4j-spring-boot-starter</artifactId>
            <version>2.0.9</version>
        </dependency>

        <!-- jwt依赖-->
        <dependency>
            <groupId>com.auth0</groupId>
            <artifactId>java-jwt</artifactId>
            <version>3.10.3</version>
        </dependency>
        <!--redis依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <!--mybatisplus依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>
<!--        spring-security依赖-->
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

02 配置系统文件

yml 复制代码
#配置redis的端口和mybatis---plus的数据源,swagger的配置信息
spring:
  redis:
    host: 127.0.0.1
    port: 6379
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/text012?userSSL=false;serverTimezone=Asia/Shanghai
    username: root
    password: 1234
  mvc:
    pathmatch:
      matching-strategy: ant_path_matcher
#开启驼峰转化,mapper的xml文件夹扫描      
mybatis-plus:
  config-locations: classpath:mapper/*.xml
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

03 配置启动类

java 复制代码
@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

04 重写UserDetailsService接口

java 复制代码
@Service
public class UserDetailsServiceImpl implements UserDetailsService {
 //这是mybatis-plus所实现的数据操作层,不使用mybatis-plus就不写
    @Autowired
    private MsUserServiceImp msUserServiceImp;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //使用mybatis-plus,获取到账号密码数据
        LambdaQueryWrapper<MsUser> qw=new LambdaQueryWrapper<>();
        qw.eq(MsUser::getUsername,username);
        MsUser user = msUserServiceImp.getOne(qw);

        //下一步就是重写UserDetails接口
        LoginUser loginUser = new LoginUser();
        loginUser.setMsUser(user);

        return loginUser;
    }
}

05 重写UserDetails接口

java 复制代码
//前三个是lombok的模块化配置,第四个是redis的序列化配置
@Data
@NoArgsConstructor
@AllArgsConstructor
@JsonIgnoreProperties(ignoreUnknown = true)
public class LoginUser implements UserDetails {

    //首先要写一个与数据库内表对应的实体类
    private MsUser msUser;
    //重写审核方法
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        return null;
    }

    //返回实体类MsUser中Password(密码)和Username(账号名对应的属性),将判断方法的返回值都改为true
    @Override
    public String getPassword() {
        return msUser.getPassword();
    }

    @Override
    public String getUsername() {
        return msUser.getUsername();
    }

    @Override
    public boolean isAccountNonExpired() {
        return true;
    }

    @Override
    public boolean isAccountNonLocked() {
        return true;
    }

    @Override
    public boolean isCredentialsNonExpired() {
        return true;
    }

    @Override
    public boolean isEnabled() {
        return true;
    }
}

四个关键点

1.UserDetails接口的实现类需要一个实体类属性(类似MsUser)
2.getPassword和getUsername方法需要返回实体类(MsUser)中代表账号名和密码的属性的值
3.五个判断账号使用的情况的方法需要返回true,不然无法正常使用

06 重写springSecurity的配置类

  • 实现WebSecurityConfigurerAdapter接口
java 复制代码
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    //需要自定义JWT过滤器
    @Autowired
    private JWTFilter jwtFilter;

    //设置密码的加密方式
    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    //关闭原有的登录接口和页面,后端只完成接口即可,让前端去画登录界面
    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http// 将自己定义的过滤器加到UsernamePasswordAuthenticationFilter之前
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
        http
                //关闭csrf
                .csrf().disable()
                //不通过Session获取SecurityContext
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                // 对于登录接口 允许匿名访问
                .antMatchers("/msUser/login").anonymous()
                // 除上面外的所有请求全部需要鉴权认证
                .anyRequest().authenticated();
    }


    //顺便设置JWT的token验证方式,这里我没重写,使用springsecurity原有的实现方式
    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

五个关键点

1.自定义JWT过滤器
2.设置密码的加密方式
3.addFilterBefore,把自定义的JWT的过滤器加到UsernamePasswordAuthenticationFilter过滤器前
4.关闭csrf(原有的登录界面和接口)
5.设置JWT的token验证方式

07 写登录实现类

  • 我这里采用mybatis-plus实现从数据库获取数据,其他方式也可
java 复制代码
@Service
public class MsUserServiceImp extends ServiceImpl<MsUserMapper, MsUser>
    implements IMsUserService {
    //注入AuthenticationManager对象
    @Autowired
    private AuthenticationManager authenticationManager;
	//写一个用于使用Redis工具类
    @Autowired
    private RedisUtil redisUtil;

	//AjaxResult是我用于设置返回的工具类,不重要
    @Override
    public AjaxResult login(MsUser user) {
        //token的验证
        UsernamePasswordAuthenticationToken token=new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword());
        Authentication authentication=authenticationManager.authenticate(token);
        if (Objects.isNull(authentication)){
            throw new RuntimeException("认证失败");
        }
        //合格说明通过
        LoginUser loginUser=(LoginUser) authentication.getPrincipal();
        //使用JWT创建token,这里我封装了一个JWT的工具类
        String jwt= JWTUtil.createToken(loginUser.getMsUser());

        try {
            redisUtil.setCacheObject("user:"+loginUser.getMsUser().getUserId(),loginUser);
        }catch (Exception e){
            e.printStackTrace();
        }


        return AjaxResult.success("登录成功",jwt);
    }
}

三个关键点

1.调用springsecurity的工具类验证前端参数
2.使用JWT工具类生成token
3.redis的数据储存

08 测试

java 复制代码
@RestController
@RequestMapping("/msUser")
public class MsUserController {
    @Autowired
    private MsUserServiceImp userServiceImp;

    @PostMapping("/login")
    public AjaxResult<String> login(MsUser user) {
        System.out.println(user);
        return userServiceImp.login(user);
    }
}
相关推荐
时差95326 分钟前
【面试题】Hive 查询:如何查找用户连续三天登录的记录
大数据·数据库·hive·sql·面试·database
让学习成为一种生活方式28 分钟前
R包下载太慢安装中止的解决策略-R语言003
java·数据库·r语言
秋意钟1 小时前
MySQL日期类型选择建议
数据库·mysql
计算机-秋大田2 小时前
基于Spring Boot的船舶监造系统的设计与实现,LW+源码+讲解
java·论文阅读·spring boot·后端·vue
Dxy12393102162 小时前
python下载pdf
数据库·python·pdf
桀桀桀桀桀桀2 小时前
数据库中的用户管理和权限管理
数据库·mysql
代码之光_19803 小时前
保障性住房管理:SpringBoot技术优势分析
java·spring boot·后端
superman超哥3 小时前
04 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索
数据库·oracle·性能优化·dba
用户8007165452003 小时前
HTAP数据库国产化改造技术可行性方案分析
数据库