若依 Spring Security 短信,扫码登录

news/2024/9/24 7:05:49/

1.  修改  LoginBody,添加登录类型字段

@Data
public class LoginBody {/*** 用户名*/private String username;/*** 用户密码*/private String password;/*** 验证码*/private String code;/*** 唯一标识*/private String uuid;/*** 登录类型*/private String loginType;
}

2.定义一个常量

package com.ruoyi.common.core.domain.constant;/*** @author Ls* @date 2024/6/4*/
public class LoginTypeConstant {public static final String PASSWORD_LOGIN = "password";public static final String MOBILE_LOGIN = "mobile";public static final String QR_CODE_LOGIN = "qrCode";
}

3.修改登录接口

    @PostMapping("/login")public AjaxResult login(@RequestBody LoginBody loginBody) {AjaxResult ajax = AjaxResult.success();loginBody.setLoginType(LoginTypeConstant.MOBILE_LOGIN);// 生成令牌String token = loginService.login(loginBody);ajax.put(Constants.TOKEN, token);return ajax;}

4.重载登录实现类,基本不用改,loginbody 作为 credentials传入UsernamePasswordAuthenticationToken 

    public String login(LoginBody loginBody) {String username = loginBody.getUsername();
//        // 验证码校验
//        validateCaptcha(username, code, uuid);
//        // 登录前置校验
//        loginPreCheck(username, password);// 用户验证Authentication authentication = null;try {UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, loginBody);AuthenticationContextHolder.setContext(authenticationToken);// 该方法会去调用UserDetailsServiceImpl.loadUserByUsernameauthentication = authenticationManager.authenticate(authenticationToken);} catch (Exception e) {if (e instanceof BadCredentialsException) {AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.password.not.match")));throw new UserPasswordNotMatchException();} else {AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, e.getMessage()));throw new ServiceException(e.getMessage());}} finally {AuthenticationContextHolder.clearContext();}AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success")));LoginUser loginUser = (LoginUser) authentication.getPrincipal();recordLoginInfo(loginUser.getUserId());// 生成tokenreturn tokenService.createToken(loginUser);}

5.自定义MyAuthenticationProvider类

package com.ruoyi.framework.security.mobile;import com.ruoyi.common.core.domain.constant.LoginTypeConstant;
import com.ruoyi.common.core.domain.model.LoginBody;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.framework.web.service.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Component;/*** @author Ls* @date 2024/6/4*/
@Component
public class MyAuthenticationProvider implements AuthenticationProvider {@Autowiredprivate UserDetailsServiceImpl userDetailsService;@Autowiredprivate BCryptPasswordEncoder bCryptPasswordEncoder;@Overridepublic Authentication authenticate(Authentication authentication) throws AuthenticationException, UserPasswordNotMatchException {String name = authentication.getName();LoginBody loginBody = (LoginBody) authentication.getCredentials();String loginType = loginBody.getLoginType();UserDetails user;switch (loginType) {case LoginTypeConstant.PASSWORD_LOGIN:user = userDetailsService.loadUserByUsername(name);String password = loginBody.getPassword();String encoderPassword = bCryptPasswordEncoder.encode(password);// 数据库账号密码的校验能通过就通过if (bCryptPasswordEncoder.matches(password, user.getPassword())) {return new UsernamePasswordAuthenticationToken(user, encoderPassword);}case LoginTypeConstant.MOBILE_LOGIN:user = userDetailsService.loadUserByPhone(loginBody);return new UsernamePasswordAuthenticationToken(user, loginBody.getCode());case LoginTypeConstant.QR_CODE_LOGIN:break;default:break;}// 如果都登录不了,就返回异常输出throw new UserPasswordNotMatchException();}@Overridepublic boolean supports(Class<?> aClass) {return true;}
}

6.用户验证类新增手机号登录 UserDetailsServiceImpl 

public UserDetails loadUserByPhone(LoginBody loginBody) throws UsernameNotFoundException {// TODO: 2024/6/4  各种业务效验,这里图省事验证码放在passwordif (!Objects.equals(loginBody.getPassword(), "123456")) {throw new ServiceException("验证码错误");}//这里应该是根据手机号查询,我这里图省事直接拿账号登录String username = loginBody.getUsername();SysUser user = userService.selectUserByUserName(username);return createLoginUser(user);}

7.SecurityConfig调整,配置一下MyAuthenticationProvider

    /*** 自定义用户认证逻辑*/@Autowiredprivate MyAuthenticationProvider myAuthenticationProvider;/*** 身份认证接口*/@Overrideprotected void configure(AuthenticationManagerBuilder auth) throws Exception {auth.authenticationProvider(myAuthenticationProvider);}

http://www.ppmy.cn/news/1468714.html

相关文章

LabVIEW开发实验室超导体电流特性测试系统

本系统旨在为学校实验室提供一个基于LabVIEW的超导体电流特性测试平台&#xff0c;通过精确测量超导体在不同温度和电流条件下的电学特性&#xff0c;帮助学生和研究人员深入理解超导体的物理性质。本文将从背景、目标、工作原理、使用方法、操作流程和注意事项等方面详细介绍该…

Mysql基础 - 事务

Mysql基础 - 事务 文章目录 Mysql基础 - 事务1 事务简介2 事务操作2.1 控制事务一2.2 控制事务二 3 事务四大特性4 并发事务问题5 事务隔离级别 1 事务简介 事务是一组操作的集合&#xff0c;他是一个不可分割的工作单位&#xff0c;事务会把所有操作作为一个整体一起向系统提…

MySQL之查询性能优化(五)

查询性能优化 查询优化器 MySQL的查询优化器是一个非常复杂的部件&#xff0c;它使用了很多优化策略来生成一个最优的执行计划。优化策略可以简单地分为两种&#xff0c;一种是静态优化&#xff0c;一种是动态优化。静态优化可以直接对解析树进行分析&#xff0c;并完成优化。…

嵌入式学习——Linux高级编程复习(进程)——day39

1. 进程 进程是计算机科学中的一个核心概念&#xff0c;它是操作系统进行资源分配和调度的基本单位&#xff0c;代表了一个正在执行中的程序实例。当一个程序被加载到内存并开始执行时&#xff0c;它就变成了一个进程。 1. 程序&#xff1a;存放在外存中的一段代码的集合 2. 进…

03-240605-Spark笔记

03-240605 1. 行动算子-1 reduce 聚合 格式: def reduce(f: (T, T) > T): T 例子&#xff1a; val sparkConf new SparkConf().setMaster("local[*]").setAppName("Operator")val sc new SparkContext(sparkConf) ​val rdd sc.makeRDD(List(1…

蓄电池MSDS报告办理 锂电池运输鉴定中英文报告申请

MSDS 指的是化学产品安全技术说明书 MSDS 报告一般是由工厂所出具的&#xff0c;但也逐渐的应用在各种贸易过程当中&#xff0c;在海运过程当中&#xff0c;相关的产品也需要提供 MSDS 认证报告&#xff0c;不过有些人对于 MSDS 认证所规定的内容不是很了解&#xff0c;接下来大…

Web前端答辩PPT模板:全面解析与高效呈现

Web前端答辩PPT模板&#xff1a;全面解析与高效呈现 在Web前端领域&#xff0c;一个优秀的答辩PPT模板不仅能够充分展示项目成果&#xff0c;还能有效传达技术实力和创新思维。本文将从四个方面、五个方面、六个方面和七个方面&#xff0c;详细解析如何打造一个高质量的Web前端…

腾讯云和windows11安装frp,实现内网穿透

一、内网穿透目的 实现公网上&#xff0c;访问到windows上启动的web服务 二、内网穿透的环境准备 公网服务器、windows11的电脑、frp软件(需要准备两个软件&#xff0c;一个是安装到公网服务器上的&#xff0c;一个是安装到windows上的) frp下载地址下载版本 1.此版本(老版…