SpringBoot+Hutool实现图片验证码

news2025/1/13 10:19:08

图片验证码在注册、登录、交易、交互等各类场景中都发挥着巨大作用,能够防止操作者利用机器进行暴力破解、恶意注册、滥用服务、批量化操作和自动发布等行为。

在这里插入图片描述
创建一个实体类封装,给前端返回的验证码数据:

@Data
public class ValidateCodeVo {

    private String codeKey ;        // 验证码的key
    private String codeValue ;      // 图片验证码对应的字符串数据

}

业务层代码实现:

public interface ValidateCodeService {

    // 获取验证码图片
    public abstract ValidateCodeVo generateValidateCode();

}
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {@Autowired
    private RedisTemplate<String , String> redisTemplate ;@Override
    public ValidateCodeVo generateValidateCode() {// 使用hutool工具包中的工具类生成图片验证码
        //参数:宽  高  验证码位数 干扰线数量
        CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 20);
        String codeValue = circleCaptcha.getCode();
        String imageBase64 = circleCaptcha.getImageBase64();// 生成uuid作为图片验证码的key
        String codeKey = UUID.randomUUID().toString().replace("-", "");// 将验证码存储到Redis中
        redisTemplate.opsForValue().set("user:login:validatecode:" + codeKey , codeValue , 5 , TimeUnit.MINUTES);// 构建响应结果数据
        ValidateCodeVo validateCodeVo = new ValidateCodeVo() ;
        validateCodeVo.setCodeKey(codeKey);
        validateCodeVo.setCodeValue("data:image/png;base64," + imageBase64);// 返回数据
        return validateCodeVo;
    }}

在Controller中添加获取验证码接口方法:

@Autowired
private ValidateCodeService validateCodeService;

@GetMapping(value = "/generateValidateCode")
public Result<ValidateCodeVo> generateValidateCode() {
    ValidateCodeVo validateCodeVo = validateCodeService.generateValidateCode();
    return Result.build(validateCodeVo , ResultCodeEnum.SUCCESS) ;
}

在登录的业务层实现验证码校验:

 /**
     * 用户登录
     * @param loginDto
     * @return
     */
    @Override
    public LoginVo login(LoginDto loginDto) {
        //获取输入的验证码和存储到redis的key名称
        String captcha = loginDto.getCaptcha();
        String key = loginDto.getCodeKey();

        //根据获取的redis的key 查询redis里面存储的验证码
        String redisCode = redisTemplate.opsForValue().get("user:validate" + key);

        // 比较输入的和redis存储验证码是否一致
        if(StrUtil.isEmpty(redisCode) || !StrUtil.equalsIgnoreCase(redisCode,captcha)){
            //提示用户,校验失败
            throw new GuiguException(ResultCodeEnum.VALIDATECODE_ERROR);
        }

        // 如果一致,删除redis里面验证码
        redisTemplate.delete("user:validate" + key);

        // 1.获取提交的用户名
        String userName = loginDto.getUserName();

        // 2.根据用户名查询用户表
        SysUser sysUser = sysUserMapper.selectUserInfoByUserName(userName);

        // 3.如果根据用户名查不到对应的信息,用户不存在,返回错误信息
        if(sysUser == null){
            //throw new RuntimeException("用户名不存在");
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }

        // 4.根据用户名查询用户信息,用户存在
        // 5.获取输入的密码,比较输入的密码和数据库的密码是否一致
        String database_assword = sysUser.getPassword();
        // 把输入的密码进行加密 再比较数据库的密码
        String input_password = DigestUtils.md5DigestAsHex(loginDto.getPassword().getBytes());

        //比较
        if(!input_password.equals(database_assword)){
//            throw new RuntimeException("密码不正确");
            throw new GuiguException(ResultCodeEnum.LOGIN_ERROR);
        }

        // 6.如果密码一致,登陆成功,如果你密码不一致登陆失败
        // 7.登陆成功,生产用户的唯一标识token
        String token = UUID.randomUUID().toString().replaceAll("-", "");

        // 8.把登陆成功的用户信息放到redis里面
        // key:token value:用户信息

        redisTemplate.opsForValue().set("user:login"+token,JSON.toJSONString(sysUser),7, TimeUnit.DAYS);
        // 9.返回loginvo对象
        LoginVo loginVo = new LoginVo();
        loginVo.setToken(token);
        return loginVo;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1374506.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JS栈和堆:数据是如何存储的

JS栈和堆&#xff1a;数据是如何存储的 背景JavaScript 是什么类型的语言JavaScript 的数据类型内存空间栈空间和堆空间再谈闭包 背景 JS有多种数据类型&#xff1a;数字型&#xff0c;字符串型&#xff0c;数组型等&#xff0c;虽然 JavaScript 并不需要直接去管理内存&#…

都2024年了,FP卖家还不知道AB站怎么玩?

自从开始写FP独立站各种运营技巧和黑科技的文章&#xff0c;经常都会有朋友来私V&#xff0c;询问怎么进行AB站跳转。 可能是现在平台对于FP商家的限制越来越多&#xff0c;再加上如今到处都是“内卷”的电商环境&#xff0c;让FP商家生存越来越艰难&#xff0c;今天就着重讲一…

美当局批准现货比特币ETF,BTC不涨反跌?解读22页官方文件,SEC的担忧被完全解决了吗?

美东时间2024年1月10日下午&#xff0c;美SEC官宣批准现货比特币ETF的上市和交易&#xff0c;这是一个里程碑时刻&#xff0c;代表着加密资产类别获得主流采用的最重要一步。 11只获得批准的现货比特币ETF分别来自&#xff1a;BlackRock、Bitwise、Grayscale、Hashdex、Valkyri…

CAN201 计网大题收集

网络性能计算 e.g1 e.g2 木桶效应 e.g3 吞吐量 e.g4 时延 e.g5 时延 e.g5 e.g e.g6 拓展 e.g7 传输层 TCP D 拥塞控制算法 拥塞控制算法_哔哩哔哩_bilibili 慢开始&#xff0c;拥塞避免&#xff0c;快重传&#xff0c;快恢复 物理层 根据我印象好像不太需要学物理层这块…

科技成果鉴定测试的意义在哪?鉴定测试报告重要吗?

科技成果鉴定测试是指通过一系列的评估和验证过程&#xff0c;对科技成果所包含的技术特征、技术优势以及市场应用前景进行客观、准确的评估和证明的过程。科技成果鉴定测试可以对科技项目进行全面、系统的评估&#xff0c;从而找出项目的优势和不足之处&#xff0c;并为项目的…

usb静电防护芯片选择

方案1 USBLC6-2SC6 优缺点 优点&#xff1a;进出使用不同的焊盘&#xff0c;如果没有焊接好信号必定不能通过。有效的避免了虚焊导致故障。 缺点&#xff1a;不能省略&#xff0c;调试时也不能省略。 原理图 参考价格 参考来源 USB切换方案&#xff0c;多电脑共用USB方案…

零基础小白如何自学sql?

学习SQL对于数据分析和处理来说非常重要。SQL是一种强大的工具&#xff0c;可以帮助你与数据库沟通&#xff0c;提取&#xff0c;整理和理解数据。 以下是一些学习SQL的建议&#xff1a; 01 前期&#xff1a;SQL数据库学习 了解SQL的基本概念&#xff1a;首先&#xff0c;你…

求幸存数之和 - 华为OD统一考试

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C++ 题目描述 给一个正整数列nums,一个跳数jump,及幸存数量left。运算过程为:从索引为0的位置开始向后跳,中间跳过 J 个数字,命中索引为 J+1 的数字,该数被敲出,并从该点起跳,以此类推,直到幸存left个数为止。…

Java高级工程师20道面试题、答案及案例

文章目录 Java高级工程师面试题、答案及案例&#xff1a; 问题&#xff1a; 在Java中&#xff0c;如何实现线程安全的单例模式&#xff1f;请写出双重检查锁定&#xff08;Double-Checked Locking&#xff09;的实现方式。 答案与案例&#xff1a; public class Singleton {pri…

电机控制----------龙伯格观测器引入

一、建立龙波格观测器 通过求解A矩阵的特征值来判断&#xff0c;整个系统是否稳定。 二、状态空间方程

ChatGPT可以帮你做什么?

学习 利用ChatGPT学习有很多&#xff0c;比如&#xff1a;语言学习、编程学习、论文学习拆解、推荐学习资源等&#xff0c;使用方法大同小异&#xff0c;这里以语言学习为例。 在开始前先给GPT充分的信息&#xff1a;&#xff08;举例&#xff09; 【角色】充当一名有丰富经验…

003-10-02【Spark官网思维笔记】香积寺旁老松树边马大爷家女儿大红用GPT学习Spark入门知识

003-10-02【Spark官网思维笔记】香积寺旁老松树边马大爷家女儿大红用GPT学习Spark入门知识. Spark 快速入门快速开始使用 Spark Shell 进行交互式分析&#xff1a;独立的应用程序其他 1, 使用 Spark Shell 进行交互式分析1.1 基本1.2 有关Dataset操作的更多信息1.3 缓存 2&…

STL-list的使用简介

目录 ​编辑 一、list的底层实现是带头双向循环链表 二、list的使用 1、4种构造函数&#xff08;与vector类似&#xff09;​编辑 2、迭代器iterator 3、容量&#xff08;capicity&#xff09;操作 4、element access 元素获取 5、增删查改 list modifiers 6、list的迭…

YOLOv8优化策略:轻量化改进 | 华为Ghostnet,超越谷歌MobileNet | CVPR2020

🚀🚀🚀本文改进:Ghost bottleneck为堆叠Ghost模块 ,与YOLOV8建立轻量C2f_GhostBottleneck 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研; 1.Ghostnet介绍 论文: https://arxiv.org/pdf/1911.11907.…

Js--数组(三)

1.什么是数组&#xff1f; 数组&#xff1a;(Array)是一种可以按顺序保存数据的数据类型 2.为什么要数组&#xff1f; 思考&#xff1a;如果我想保存一个班里所有同学的姓名怎么办&#xff1f; 场景&#xff1a;如果有多个数据可以用数组保存起来&#xff0c;然后放到一个变量…

合并 PDF 文件的7个免费软件

PDF 合并是将所需信息转移到一个文件夹中的最佳选择&#xff0c;因此&#xff0c;您需要最好的 pdf 合并软件。 在 PDF 中复制粘贴不同的格式然后进行编辑非常耗时。因此&#xff0c;请查看我们的首选免费软件以合并 PDF 文件。 此列表中的工具可让您一次处理大量文件&#x…

STM32 ADC采样调试笔记

最近在搞STM32L051系列一个小MCU&#xff0c;要用这个去采集两路ADC作为输入。期间也碰到过一些问题&#xff0c;顺便记录下。 ADC采集原理不说了&#xff0c;主要采集电压&#xff0c;用数字进行细分&#xff0c;这样就可以知道输入电压多少了&#xff0c;网上也有很多相关文…

【附源码】基于SSM+Java的题库管理系统的设计与实现

基于SSMJava的题库管理系统的设计与实现 &#x1f345; 作者主页 央顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;We…

一小时掌握:使用ScrapySharp和C#打造新闻下载器

引言 爬虫技术是指通过编程的方式&#xff0c;自动从互联网上获取和处理数据的技术。爬虫技术有很多应用场景&#xff0c;比如搜索引擎、数据分析、舆情监测、电商比价等。爬虫技术也是一门有趣的技术&#xff0c;可以让你发现网络上的各种有价值的信息。 本文将介绍如何使用…

Linux -- Nginx服务基础

4.1Nginx服务基础 Nginx(发音为[engine x])专为性能优化而开发&#xff0c;其最知名的优点是它的稳定性和低系统资源消 耗&#xff0c;以及对HTTP并发连接的高处理能力&#xff08;单台物理服务器可支持30000~50000个并发请求&#xff09;&#xff0c;正因 为如此&#xff0c;…