• 前后端分离项目验证码实现


    一、验证码实现流程:

    1、后端使用工具生成二维码(包括image的字符串和code字符);

    2、使用uuid生成唯一的key值,将key和code以键值对的形式存储到redis缓存中,设置过期时间;

    3、将image字符串和key值发送给前端,前端将image字符串转换成图片渲染到页面;

    4、将用户输入的验证码和接收的key值一起发送给后端;

    5、后端使用key从redis中读取code值,(转大小写)进行比对;

    6、比对成功执行相关操作,比对失败进行相关操作;

    二、代码实现

    1、使用 CaptchaUtil 工具类生成二维码,存入 redis 中并返回给前端

    1. @Service
    2. public class CheckCodeServiceImpl implements CheckCodeService {
    3. @Autowired
    4. RedisTemplate redisTemplate;
    5. @Override
    6. public CheckCode getCheckCode() {
    7. // 150、50为图形的长、宽。 4表示生成4位验证码,2表示干扰线是2位,并放入redis
    8. CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(150, 50, 4, 2);
    9. //code验证码
    10. String codeValue = circleCaptcha.getCode();
    11. //图片验证码
    12. String imageBase64 = circleCaptcha.getImageBase64();
    13. //添加文件头部
    14. //"data:images/png;base64,"+imageBase64 直接显示
    15. String img = "data:images/png;base64," +imageBase64;
    16. //生成唯一key
    17. String uuid = UUID.randomUUID().toString();
    18. String key = uuid.replace("-", "");
    19. //存入redis,并设置过期时间
    20. redisTemplate.opsForValue().set(key, codeValue, 3, TimeUnit.MINUTES);
    21. //封装返回对象
    22. CheckCode checkCode = new CheckCode();
    23. checkCode.setCheckImg(img);
    24. checkCode.setCheckMessage(key);
    25. return checkCode;
    26. }
    27. }

    2、前端接收并渲染到页面

    1. //js代码
    2. //验证
    3. const checkImg = ref("")
    4. const getCheckCode = async()=>{
    5. return request.get(`/checkCode/get`)
    6. }
    7. //html代码
    8. "login_span">
    9. 验证码:
    10. "user.checkCode" style="width: 210px;height:40px;margin-bottom:30px;" placeholder="Please input" />
    11. "width: 100px; height: 40px;margin-left: 10px;cursor:pointer;" :src="checkImg" :fit="fit"/>
  • 3、前端向后端发送校验请求并携带key和验证码

    1. //登录
    2. const user = reactive({
    3. username: "",
    4. password: "",
    5. //输入的验证码
    6. checkCode:"",
    7. //key
    8. checkMessage:""
    9. })
    10. async function(){
    11. const {data} = await request.post(`/auth/login`,user)
    12. }

    4、后端收到请求,进行校验

    1. @Override
    2. public String login(LoginDto loginDto) {
    3. //验证码验证
    4. String checkCode = loginDto.getCheckCode();
    5. String queryCode = redisTemplate.opsForValue().get(loginDto.getCheckMessage());
    6. //统一为小写比较
    7. String lowerCaseCheckCode = checkCode.toLowerCase();
    8. String lowerCasequeryCode = queryCode.toLowerCase();
    9. if(!lowerCaseCheckCode.equals(lowerCasequeryCode)){
    10. throw new RuntimeException("验证码错误");
    11. }
    12. //删除验证码缓存
    13. redisTemplate.delete(loginDto.getCheckMessage());
    14. //获取认证方法进行认证
    15. String username = loginDto.getUsername();
    16. LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper().eq(User::getUsername, username);
    17. User user = userMapper.selectOne(queryWrapper);
    18. if(null == user){
    19. throw new RuntimeException("用户不存在");
    20. }
    21. //比较密码
    22. String passwordDb = user.getPassword();
    23. String password = loginDto.getPassword();
    24. boolean matches = passwordEncoder.matches(password, passwordDb);
    25. if(!matches){
    26. throw new RuntimeException("密码错误");
    27. }
    28. int id = user.getId();
    29. String userid = String.valueOf(id);
    30. //生成jwt
    31. String jwt = JwtUtils.createJWT(userid);
    32. //将用户信息转换成json数据
    33. String jsonString = JSON.toJSONString(user);
    34. //将用户信息存入redis
    35. redisTemplate.opsForValue().set("userId:"+userid,jsonString,30, TimeUnit.MINUTES);
    36. //返回给前端令牌
    37. return jwt;
    38. }

  • 相关阅读:
    京东API接口大全
    (Note)同比和环比
    【云计算•云原生】5.云原生之初识DevOps
    Java“牵手”微店商品详情数据,微店商品详情API接口,微店API接口申请指南
    Go语言的100个错误使用场景(11-20)|项目组织和数据类型
    【高项笔记】No.3 网络接入技术和网络规划与设计
    firewalld防火墙处理的命令
    基于C++的朴素贝叶斯分类器
    【笑小枫的SpringBoot系列】【十一】SpringBoot接口日志信息统一记录
    CSS的元素显示模式
  • 原文地址:https://blog.csdn.net/qh1112/article/details/140044232