SpringBoot+Hutool实现图片验证码

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

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

@Data
public class ValidateCodeVo {private String codeKey ;        // 验证码的keyprivate String codeValue ;      // 图片验证码对应的字符串数据}

业务层代码实现:

public interface ValidateCodeService {// 获取验证码图片public abstract ValidateCodeVo generateValidateCode();}
@Service
public class ValidateCodeServiceImpl implements ValidateCodeService {@Autowiredprivate RedisTemplate<String , String> redisTemplate ;@Overridepublic ValidateCodeVo generateValidateCode() {// 使用hutool工具包中的工具类生成图片验证码//参数:宽  高  验证码位数 干扰线数量CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 20);String codeValue = circleCaptcha.getCode();String imageBase64 = circleCaptcha.getImageBase64();// 生成uuid作为图片验证码的keyString 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*/@Overridepublic 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.登陆成功,生产用户的唯一标识tokenString 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.mzph.cn/news/611587.shtml

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

相关文章

一、数据结构基本概念

数据结构基本概念 一、数据结构基本概念1.基本概念和术语1.1数据&#xff08;Data&#xff09;1.2 数据元素&#xff08;Data element&#xff09;1.3 数据项 &#xff08;Data Item&#xff09;1.4 数据对象 &#xff08;Data Object&#xff09;1.5 数据结构 &#xff08;Dat…

基于 Validator 类实现 ParamValidator,用于校验函数参数

目录 一、前置说明1、总体目录2、相关回顾3、本节目标 二、操作步骤1、项目目录2、代码实现3、测试代码4、日志输出 三、后置说明1、要点小结2、下节准备 一、前置说明 1、总体目录 《 pyparamvalidate 参数校验器&#xff0c;从编码到发布全过程》 2、相关回顾 使用 TypeV…

Every Nobody Is Somebody 「每小人物都能成大事」

周星驰 NFT Nobody即将发售&#xff0c;Nobody共创平台 Every Nobody Is Somebody Nobody 关于Nobody&#xff1a;Nobody是一款Web3共创平台&#xff0c;旨在为创作者提供一个交流和合作的场所&#xff0c;促进创意的产生和共享。通过该平台&#xff0c;创作者可以展示自己的作…

git秘钥过期 ERROR: Your SSH key has expired

文章目录 1、错误提示Your SSH key has expired2、登录Github确认3、重新设置秘钥 1、错误提示Your SSH key has expired 使用git命令时遇到Github 的 SSH Key秘钥过期&#xff0c;提示错误ERROR: Your SSH key has expired 2、登录Github确认 首先登录Github查看&#xff…

L1-015 跟奥巴马一起画方块(Java)

美国总统奥巴马不仅呼吁所有人都学习编程&#xff0c;甚至以身作则编写代码&#xff0c;成为美国历史上首位编写计算机代码的总统。2014年底&#xff0c;为庆祝“计算机科学教育周”正式启动&#xff0c;奥巴马编写了很简单的计算机代码&#xff1a;在屏幕上画一个正方形。现在…

某查查请求头参数加密分析(含JS加密算法与Python爬虫源码)

文章目录 1. 写在前面2. 请求分析3. 断点分析4. 扣加密JS5. Python爬虫代码实现 【作者主页】&#xff1a;吴秋霖 【作者介绍】&#xff1a;Python领域优质创作者、阿里云博客专家、华为云享专家。长期致力于Python与爬虫领域研究与开发工作&#xff01; 【作者推荐】&#xff…

基于SELinux三权分立配置方法

1.系统安装 系统安装完成后,系统当前的SELinux配置为: # cat /etc/selinux/config SELINUX=enforcing SELINUXTYPE=targeted 2.SELinux环境准备 # yum install setools policycoreutils.x86_64 selinux-policy-mls.noarch setroubleshoot.x86_64 setools-console -y 3.SELin…

嵌入式c语言学习笔记:可重入函数与不可重入函数

什么是可重入函数与不可重入函数&#xff1f; 在一个多任务环境中&#xff0c;一个函数如果可以被多次重复调用&#xff0c;或者被多个任务并发调用&#xff0c;函数在运行过程中可以随时随地被打断&#xff0c;并不影响该函数的运行结果&#xff0c;我们称这样的函数为可重入…

Redis 常用的数据类型及用法

1. 字符串&#xff08;Strings&#xff09; 字符串是最基本的 Redis 数据类型。它可以包含任何形式的数据&#xff0c;比如文本、数字或二进制数据。 基本用法&#xff1a; 设置值: SET key value获取值: GET key删除键: DEL key自增: INCR key追加值: APPEND key value 示…

vue element plus TimePicker 时间选择器

用于选择或输入日期 TIP 在 SSR 场景下&#xff0c;您需要将组件包裹在 <client-only></client-only> 之中 (如: Nuxt) 和 SSG (e.g: VitePress). 任意时间点# 可以选择任意时间 提供了两种交互方式&#xff1a;默认情况下通过鼠标滚轮进行选择&#xff0c;打开…

三、java线性表(顺序表、链表、栈、队列)

java线性表 三、线性表1.1 顺序表1.2 链表1.2.1 单向链表&#xff08;Singly Linked List&#xff09;1.2.2 双向链表&#xff08;Doubly Linked List&#xff09; 1.3 LinkedList VS ArrayList1.3.7 使用 LinkedList 的场景 1.4 栈1.5 队列 三、线性表 线性表是一种经典的数据…

LeetCode2696. Minimum String Length After Removing Substrings

文章目录 一、题目二、题解 一、题目 You are given a string s consisting only of uppercase English letters. You can apply some operations to this string where, in one operation, you can remove any occurrence of one of the substrings “AB” or “CD” from s…

手撕单链表(单向,不循环,不带头结点)的基本操作

&#x1d649;&#x1d65e;&#x1d658;&#x1d65a;!!&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦&#x1f44f;&#x1f3fb;‧✧̣̥̇‧✦ &#x1f44f;&#x1f3fb;‧✧̣̥̇:Solitary-walk ⸝⋆ ━━━┓ - 个性标签 - &#xff1a;来于“云”的“羽球人”。…

mercury靶机

文章妙语 不与伪君子争名&#xff0c;不与真小人争利&#xff0c;不与执拗人争理&#xff0c;不与匹夫争勇&#xff0c;不与酸儒争才。不与蠢人施恩 一、信息收集 主机探测 端口探测 探测主机详细版本信息 8080开了http服务 目录扫描 robots.txt目录下什么也没有 二&#xff0…

Python | Iter/genartor | 一文了解迭代器、生成器的含义\区别\优缺点

前提 一种技术的出现&#xff0c;需要考虑&#xff1a; 为了实现什么样的需求&#xff1b;遇到了什么样的问题&#xff1b;采用了什么样的方案&#xff1b;最终接近或达到了预期的效果。 概念 提前理解几个概念&#xff1a; 迭代 我们经常听到产品迭代、技术迭代、功能迭代…

oracle常用内部表和视图

Oracle数据库中存在大量内部表和视图&#xff0c;主要用于系统管理和维护。这里列出一些常用的内部视图&#xff08;数据字典视图&#xff09;和内部表&#xff1a; **常用内部视图&#xff08;Data Dictionary Views&#xff09;&#xff1a;** 1. **用户权限相关视图&#…

零基础学习数学建模——(二)数学建模的步骤

本篇博客将详细介绍数学建模的步骤。 文章目录 引例&#xff1a;年夜饭的准备第一步&#xff1a;模型准备第二步&#xff1a;模型假设第三步&#xff1a;模型建立第四步&#xff1a;模型求解第五步&#xff1a;结果分析第六步&#xff1a;模型检验第七步&#xff1a;模型应用及…

爬虫案例—抓取小米商店应用

爬虫案例—抓取小米商店应用 代码如下&#xff1a; # 抓取第一页的内容 import requests from lxml import etree url ‘https://app.mi.com/catTopList/0?page1’ headers { ‘User-Agent’: ‘Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (K…

go中for range的坑以及解决方案

一、for range的坑 相信小伙伴都遇到过以下的循环变量的问题&#xff0c;那是因为循环的val变量是重复使用的&#xff0c;即仅有一份。也就是说&#xff0c;每次循环后赋给val的值就会把前面循环赋给val的值替换掉&#xff0c;所以打印出来的值都是最后一次循环赋给val的值。 …

openeuler的安装和两台linux主机配置ssh实现互相免密登陆

一、openeuler的安装 下载OpenEuler - 网址&#xff1a;https://www.openeuler.org/zh/download/archive/ - 版本选择&#xff1a;openEuler 22.03 LTS SP2 &#xff08;镜像文件&#xff09; &#xff0c;即长期更新版 设置自定义硬件 内存&#xff1a;推荐2GB 处理器&…