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);
    }
}
相关推荐
薛晓刚24 分钟前
当MySQL的int不够用了
数据库
SelectDB技术团队1 小时前
Apache Doris 在菜鸟的大规模湖仓业务场景落地实践
数据库·数据仓库·数据分析·apache doris·菜鸟技术
星空下的曙光1 小时前
mysql 命令语法操作篇 数据库约束有哪些 怎么使用
数据库·mysql
小楓12011 小时前
MySQL數據庫開發教學(一) 基本架構
数据库·后端·mysql
白仑色1 小时前
Spring Boot 全局异常处理
java·spring boot·后端·全局异常处理·统一返回格式
染落林间色1 小时前
达梦数据库-实时主备集群部署详解(附图文)手工搭建一主一备数据守护集群DW
数据库·sql
Monly211 小时前
RabbitMQ:SpringAMQP 入门案例
spring boot·rabbitmq·java-rabbitmq
Monly211 小时前
RabbitMQ:SpringAMQP Fanout Exchange(扇型交换机)
spring boot·rabbitmq·java-rabbitmq
每天学习一丢丢2 小时前
Spring Boot + Vue 项目用宝塔面板部署指南
vue.js·spring boot·后端
颜颜yan_2 小时前
企业级时序数据库选型指南:从传统架构向智能时序数据管理的转型之路
数据库·架构·时序数据库