SpringBoot使用 easy-captcha 实现验证码登录功能
文章目录
- 一、 环境准备
- 1. 解决思路
- 2. 接口文档
- 3. redis下载
- 二、后端实现
- 1. 引入依赖
- 2. 添加配置
- 3. 后端代码实现
- 4. 前端代码实现
在前后端分离的项目中,登录功能是必不可少的。为了提高安全性,通常会加入验证码验证。
easy-captcha 是一个简单易用的验证码生成库,支持多种类型的验证码(如字符、中文、算术等)。本文将介绍如何在 Spring Boot 后端和 Vue.js 前端中集成
easy-captcha,实现验证码登录功能。
一、 环境准备
1. 解决思路
- 后端使用 easy-captcha 创建验证码对象。
- 将验证码文本存储到 Redis 中,并生成一个随机的 key。
- 将验证码的 Base64 字符串和 key 返回给前端。
- 前端通过 Base64 字符串显示验证码图片,并将 key 保存起来。
- 登录时,前端将用户输入的验证码和 key 发送到后端。
- 后端通过 key 从 Redis 中获取验证码文本,并进行比对验证。
2. 接口文档
URL
GET /captcha
参数
无
返回
{"msg": "操作成功","code": 200,"data": {"uuid": "b71fafb1a91b4961afb27372bd3af77c","captcha": "data:image/png;base64,iVBORw0KGgoAAAA","code": "nrew"}
}
3. redis下载
见 redis安装配置教程
二、后端实现
1. 引入依赖
在 pom.xml 文件中引入 easy-captcha 和 Redis 相关依赖:
<dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2. 添加配置
在application.yml里添加连接redis数据库的配置信息:
spring:redis:open: truedatabase: 1host: localhostport: 6379
3. 后端代码实现
controller:
@RestController
public class LoginController {@Autowiredprivate RedisTemplate redisTemplate;@GetMapping("/captcha")public Result captcha() {// 创建一个 SpecCaptcha 对象,设置验证码图片的宽度、高度和字符长度SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 4);// 生成验证码文本,并将其转换为小写(方便后续比较,忽略大小写)String code = specCaptcha.text().toLowerCase();// 生成一个唯一的 UUID,用于存储验证码到 Redis 中String uuid = IdUtil.simpleUUID();// 将验证码文本存入 Redis,并设置过期时间为 2 分钟(120 秒)// 这样可以确保验证码在一定时间后自动失效,避免被恶意利用this.redisTemplate.opsForValue().set(uuid, code, 120, TimeUnit.SECONDS);// 创建一个 Map,用于存储返回给前端的数据Map<String, String> map = new HashMap<String, String>(3);// 将 UUID 存入 Map,前端需要将这个 UUID 一起发送到后端进行验证map.put("uuid", uuid);// 将生成的验证码文本存入 Map(可选,通常前端不需要知道验证码文本)map.put("code", code);// 将验证码图片转换为 Base64 字符串,并存入 Map// 前端可以通过这个 Base64 字符串生成验证码图片map.put("captcha", specCaptcha.toBase64());// 返回 Result 对象,其中包含验证码图片的 Base64 字符串和 UUID// Result.ok() 表示操作成功,put("data", map) 将 Map 数据放入响应中return Result.ok().put("data", map);}@PostMapping("/login")public Result login(@RequestBody LoginForm loginForm, HttpSession session){//验证码校验String code = (String) this.redisTemplate.opsForValue().get(loginForm.getUuid());//判断验证码是否有效if(code == null){return Result.error("验证码已过期");}//判断验证码是否正确if(!code.equals(loginForm.getCaptcha())){return Result.error("验证码错误");}//判断用户名是否正确QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("username", loginForm.getUsername());User user = this.userService.getOne(queryWrapper);if(user == null){return Result.error("用户名错误");}//判断密码是否正确String password = SecureUtil.sha256(loginForm.getPassword());if(!password.equals(user.getPassword())){return Result.error("密码错误");}//验证用户是否可用if(user.getStatus() == 0) {return Result.error("账号已被锁定,请联系管理员");}//登录成功session.setAttribute("user", user);//创建tokenString token = this.jwtUtil.createToken(String.valueOf(user.getUserId()));this.redisTemplate.opsForValue().set("communityuser-"+user.getUserId(), token,jwtUtil.getExpire());Map<String,Object> map = new HashMap<>();map.put("token", token);map.put("expire", jwtUtil.getExpire());LogAspect.user = user;return Result.ok().put("data", map);}
}
RedisTemplate 是 Spring Data Redis 提供的一个高级抽象,封装了 Redis 的操作。它支持多种数据结构(如字符串、列表、集合、哈希等),并提供了丰富的操作方法。通过 RedisTemplate,可以方便地执行 Redis 命令,而无需直接使用 Redis 的原生客户端。
常用方法:
- opsForValue():用于操作 Redis 中的字符串(
String)数据。 - opsForList():用于操作 Redis 中的列表(
List)数据。 - opsForSet():用于操作 Redis 中的集合(
Set)数据。 - opsForHash():用于操作 Redis 中的哈希(
Hash)数据。 - opsForZSet():用于操作 Redis 中的有序集合(
Sorted Set)数据。
4. 前端代码实现
- 获取验证码
前端通过调用后端接口获取验证码图片和 UUID。这个 UUID 用于在后端标识验证码的唯一性。
// 获取验证码
getCaptcha() {getCaptchaImg().then(res => {this.captchaPath = res.data.captcha; // 将验证码图片的 Base64 字符串赋值给 captchaPaththis.loginForm.uuid = res.data.uuid; // 将 UUID 赋值给 loginForm 的 uuid 属性if (process.env.NODE_ENV === 'development') {this.loginForm.captcha = res.data.code; // 在开发环境中自动填充验证码(方便测试)}});
}
- 显示验证码
前端通过 el-image 组件显示验证码图片,并提供点击刷新功能。
<el-imageclass="captcha-img":src="captchaPath" <!-- 绑定验证码图片的 Base64 字符串 -->@click="getCaptcha()" <!-- 点击图片时重新获取验证码 -->
/>
3. 提交表单时验证验证码
用户输入验证码后,点击登录按钮提交表单。前端将用户输入的验证码和 UUID 一起发送到后端进行验证。
handleLogin() {this.$refs.loginForm.validate(valid => {if (valid) {this.loading = true;this.$store.dispatch('user/login', this.loginForm).then(() => {this.$router.push({ path: this.redirect || '/' }); // 登录成功后跳转}).catch(() => {this.getCaptcha(); // 登录失败,重新获取验证码this.loading = false;});} else {return false;}});
}

相关文章:
SpringBoot使用 easy-captcha 实现验证码登录功能
文章目录 一、 环境准备1. 解决思路2. 接口文档3. redis下载 二、后端实现1. 引入依赖2. 添加配置3. 后端代码实现4. 前端代码实现 在前后端分离的项目中,登录功能是必不可少的。为了提高安全性,通常会加入验证码验证。 easy-captcha 是一个简单易用的验…...
DIY Shell:探秘进程构建与命令解析的核心原理
个人主页:chian-ocean 文章专栏-Linux 前言: Shell(外壳)是一个操作系统的用户界面,它提供了一种方式,使得用户能够与操作系统进行交互。Shell 是用户与操作系统之间的桥梁,允许用户通过命令行…...
数据库备份、主从、集群等配置
数据库备份、主从、集群等配置 1 MySQL1.1 docker安装MySQL1.2 主从复制1.2.1 主节点配置1.2.2 从节点配置1.2.3 创建用于主从同步的用户1.2.4 开启主从同步1.2.4 主从同步验证 1.3 主从切换1.3.1 主节点设置只读(在192.168.1.151上操作)1.3.2 检查主从数…...
【数据采集】基于Selenium采集豆瓣电影Top250的详细数据
基于Selenium采集豆瓣电影Top250的详细数据 Selenium官网:https://www.selenium.dev/blog/ 豆瓣电影Top250官网:https://movie.douban.com/top250 写在前面 实验目标:基于Selenium框架采集豆瓣电影Top250的详细数据。 电脑系统:Windows 使用软件:PyCharm、Navicat 技术需求…...
(回溯递归dfs 电话号码的字母组合 remake)leetcode 17
只找边界条件和非边界条件,剩下的交给数学归纳法就行,考虑子问题的重复性 [class Solution {vector<string>str { "","","abc","def","ghi","jkl","mno","pqrs"…...
Redis --- 使用zset处理排行榜和计数问题
在处理计数业务时,我们一般会使用一个数据结构,既是集合又可以保证唯一性,所以我们会选择Redis中的set集合: 业务逻辑: 用户点击点赞按钮,需要再set集合内判断是否已点赞,未点赞则需要将点赞数1…...
响应式编程_04Spring 5 中的响应式编程技术栈_WebFlux 和 Spring Data Reactive
文章目录 概述响应式Web框架Spring WebFlux响应式数据访问Spring Data Reactive 概述 https://spring.io/reactive 2017 年,Spring 发布了新版本 Spring 5, Spring 5 引入了很多核心功能,这其中重要的就是全面拥抱了响应式编程的设计思想和实…...
C++ Primer 算术运算符
欢迎阅读我的 【CPrimer】专栏 专栏简介:本专栏主要面向C初学者,解释C的一些基本概念和基础语言特性,涉及C标准库的用法,面向对象特性,泛型特性高级用法。通过使用标准库中定义的抽象设施,使你更加适应高级…...
中位数定理:小试牛刀> _ <2025牛客寒假1
给定数轴上的n个点,找出一个到它们的距离之和尽量小的点(即使我们可以选择不是这些点里的点,我们还是选择中位数的那个点最优) 结论:这些点的中位数就是目标点。可以自己枚举推导(很好想) (对于 点的数量为…...
一些常用的HTML结构
1. 页面基本结构 DOCTYPE 声明: 作用:告知浏览器使用哪种 HTML 版本进行解析。示例: <!DOCTYPE html><html> 标签: 作用:作为整个 HTML 文档的根元素,包含文档的头部和主体。示例࿱…...
js的 encodeURI() encodeURIComponent() decodeURI() decodeURIComponent() 笔记250205
js的 encodeURI() encodeURIComponent() decodeURI() decodeURIComponent() 在JavaScript中,处理URI编码和解码的四个关键函数为:encodeURI()、encodeURIComponent()、decodeURI()和decodeURIComponent()。它们分别用于不同的场景,具体区别和…...
安全实验作业
一 拓扑图 二 要求 1、R4为ISP,其上只能配置IP地址;R4与其他所有直连设备间均使用共有IP 2、R3-R5-R6-R7为MGRE环境,R3为中心站点; 3、整个OSPF环境IP基于172.16.0.0/16划分; 4、所有设备均可访问R4的环回&#x…...
《Python预训练视觉和大语言模型》:从DeepSeek到大模型实战的全栈指南
就是当代AI工程师的日常:* - 砸钱买算力,却卡在分布式训练的“隐形坑”里; - 跟着论文复现模型,结果连1/10的性能都达不到; - 好不容易上线应用,却因伦理问题被用户投诉…… 当所有人都在教你怎么调用…...
血压计OCR文字检测数据集VOC+YOLO格式2147张11类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):2147 标注数量(xml文件个数):2147 标注数量(txt文件个数):2147 …...
Java 面试合集(2024版)
种自己的花,爱自己的宇宙 目录 第一章-Java基础篇 1、你是怎样理解OOP面向对象??? 难度系数:? 2、重载与重写区别??? 难度系数:? 3、接口与抽象类的区别??? 难度系数:? 4、深拷贝与浅拷贝的理解??? 难度系数&…...
Typora免费使用
一.下载地址 https://typoraio.cn/ 二.修改配置文件 1.找到安装路径下的LicenseIndex.180dd4c7.4da8909c.chunk.js文件 文件路径为:安装路径\resources\page-dist\static\js\LicenseIndex.180dd4c7.4da8909c.chunk.js 将js中的 e.hasActivated"true"e.hasActiva…...
第一性原理:游戏开发成本的思考
利润 营收-成本 营收定价x销量x分成比例 销量 曝光量x 点击率x (购买率- 退款率) 分成比例 100%- 平台抽成- 税- 引擎费- 发行抽成 成本开发成本运营成本 开发成本 人工外包办公地点租金水电设备折旧 人工成本设计成本开发成本迭代修改成本后续内容…...
裁员潮血洗硅谷,普通人惨遭裁员的血泪教训——要随时做好失业的准备
我大学室友21年暑假在meta的某AI组实习过,压力巨大!组里大群天天消息99,年底实习结束直接就进到Google去了,听说eng组的intern十有八九都拿到了return offer,但都利用空余时间跳到了别的大厂。 离谱的时候,…...
MacBook Pro(M1芯片)Qt环境配置
MacBook Pro(M1芯片)Qt环境配置 1、准备 试图写一个跨平台的桌面应用,此时想到了使用Qt,于是开始了搭建开发环境~ 在M1芯片的电脑上安装,使用brew工具比较方便 Apple Silicon(ARM/M1…...
智能编码在前端研发的创新应用
一、前端开发实例 今天主要想分享一些关于大模型如何协助我们进行前端编码的实践。首先,让我们以一个前端开发的实例开始。通常,当需要实现一个新的前端功能时,我们会收到相关的背景和需求描述。我的期望是,大模型能够直接使用这…...
[特殊字符] ChatGPT-4与4o大比拼
🔍 ChatGPT-4与ChatGPT-4o之间有何不同?让我们一探究竟! 🚀 性能与速度方面,GPT-4-turbo以其优化设计,提供了更快的响应速度和处理性能,非常适合需要即时反馈的应用场景。相比之下,G…...
在Spring Cloud中将Redis共用到Common模块
前言 在分布式系统中,共用组件的设计可以极大地提升代码复用性和维护性。Spring Cloud中将Redis共用到一个公共模块(common模块)是一个常见的设计实践,这样可以让多个微服务共享相同的Redis配置和操作逻辑。本文将详细介绍如何在…...
基于RK3588/RK3576+MCU STM32+AI的储能电站电池簇管理系统设计与实现
伴随近年来新型储能技术的高质量规模化发展,储能电站作为新能源领域的重要载体, 旨在配合逐步迈进智能电网时代,满足电力系统能源结构与分布的创新升级,给予相应规模 电池管理系统的设计与实现以新的挑战。同时,电子系…...
Django框架丨从零开始的Django入门学习
Django 是一个用于构建 Web 应用程序的高级 Python Web 框架,Django是一个高度模块化的框架,使用 Django,只要很少的代码,Python 的程序开发人员就可以轻松地完成一个正式网站所需要的大部分内容,并进一步开发出全功能…...
稀疏混合专家架构语言模型(MoE)
注:本文为 “稀疏混合专家架构语言模型(MoE)” 相关文章合辑。 手把手教你,从零开始实现一个稀疏混合专家架构语言模型(MoE) 机器之心 2024年02月11日 12:21 河南 选自huggingface 机器之心编译 机器之心…...
spring基础总结
先修知识:依赖注入,反转控制,生命周期 IDEA快捷键 Ctrl Altm:提取方法,设置trycatch 通用快捷键: Ctrl F:在当前文件中查找文本。Ctrl R:在当前文件中替换文本。Ctrl Z:撤销…...
【C#】Process、ProcessStartInfo启动外部exe
在C#中使用 Process 和 ProcessStartInfo 类启动外部 .exe 文件,可以按照以下步骤进行: 创建 ProcessStartInfo 实例:配置进程启动信息,包括可执行文件的路径、传递给该程序的参数等。 设置启动选项:根据需要配置 Pro…...
【实用小技巧】如何不更新application.yml而更新spring的配置
大家都知道,我们在java工程中,常常在application.yml中有各种各样的运行时的配置,一般来说都是这样的结构: a:b:c: {ENV_NAME} 这样,我们在部署应用时,就可以通过在不同的局点修改ENV_NAME的值࿰…...
windows linux常用基础命令
windows基础命令 cd …/ (访问D盘 直接D: 进入目录cd…\baidudu) color 2 改变颜色 dir 浏览当前目录中有什么内容 例如 dir windows可以浏览windows中有什么文件 cls 清屏 cd windows 可以跳转到c盘目录的下面 cd…/可以返回到上一级目录 ./当前目录 cd \ 直…...
openRv1126 AI算法部署实战之——TensorFlow TFLite Pytorch ONNX等模型转换实战
Conda简介 查看当前系统的环境列表 conda env list base为基础环境 py3.6-rknn-1.7.3为模型转换环境,rknn-toolkit版本V1.7.3,python版本3.6 py3.6-tensorflow-2.5.0为tensorflow模型训练环境,tensorflow版本2.5.0,python版本…...
