当前位置: 首页 > news >正文

Java后端图形验证码的使用

一、验证码使用逻辑

在这里插入图片描述

二、生成验证码

使用Kaptcha库生成验证码
这里使用的是后端调用Kaptcha库生成验证码的二进制字符串,传给前端,由前端转为图片

1、引入依赖

		<dependency><groupId>com.github.penggle</groupId><artifactId>kaptcha</artifactId><version>2.3.2</version></dependency>

2、生成验证码

// 生成验证码
String code = kaptchaProducer.createText();

3、根据文本生成验证码图片(BufferedImage对象)

BufferedImage kaptchaImage = kaptchaProducer.createImage(code);

4、将图片转换为Base64

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ImageIO.write(kaptchaImage, "jpg", outputStream);
String base64Img = Base64.getEncoder().encodeToString(outputStream.toByteArray());

ByteArrayOutputStream:内存输出流,用于临时存储图片二进制数据。

ImageIO.write:将BufferedImage以JPEG格式写入输出流。

Base64编码:将二进制图片数据转换为Base64字符串,便于前端通过直接显示。

5、构造返回前端的响应

Map<String, String> imgMap = new HashMap<>();
imgMap.put(key, "data:image/jpeg;base64," + base64Img);

返回值格式:生成一个键值对,例如:

{ "captchaKey": "data:image/jpeg;base64,/9j/4AAQSkZJRgA..." }

key的作用:前端提交验证码时需携带此键,服务端通过它从缓存中获取正确的验证码文本。

6、缓存验证码

Map<String, String> cacheMap = new HashMap<>();
cacheMap.put(CODE, code.toUpperCase());
captchaCache.putCaptcha(key, cacheMap);

Google Guava 缓存库实现的验证码缓存组件,用于在单节点部署环境中存储和验证验证码信息。

  1. 转换为大写:code.toUpperCase()使验证码不区分大小写(用户输入a3g7或A3G7均可通过)。
  2. 缓存逻辑:
  • CODE是常量(如"code"),作为缓存Map的键。
  • captchaCache是自定义缓存组件,将key与验证码文本关联,通常设置有效期
@Override
public boolean putCaptcha(String key, Map<String, String> value) {try {cache.put(key, JSONObject.fromObject(value).toString());} catch (Exception ex) {return false;}return true;
}

三、验证验证码

一般在调用登录接口前验证验证码,通过SpringMVC的拦截器实现
1、验证验证码,判断是否为空

		if(StringUtil.isEmpty(key)) {throw new BadRequestAlertException(ErrorConstants.CAPTCHA_TYPE, "The information of captcha is missing", "captcha.header", "missing");}

2、获取验证码(如果验证码过期则无法获取到)

Map<String, String> validateMap = captchaCache.getCaptcha(key);

3、删除验证码缓存

captchaCache.deleteCaptcha(key);

4、比较验证码的值

		if(captcha.get(CODE).equalsIgnoreCase(validateMap.get(CODE))){return true;}

相关文章:

  • [Linux网络_68] 转发 | 路由(Hop by Hop) | IP的分片和组装
  • 当OA闯入元宇宙:打卡、报销和会议的未来狂想
  • 【C++11】包装器:function与bind
  • 【BotSharp框架示例 ——实现聊天机器人,并通过 DeepSeek V3实现 function calling】
  • 【MuJoCo仿真】开源SO100机械臂导入到仿真环境
  • 在 Ubuntu 上离线安装 ClickHouse
  • ShaderToy学习笔记 05.3D旋转
  • 人工智能数学基础(三):微积分初步
  • 深入解析常见排序算法及其 C# 实现
  • 初识Redis · 分布式锁
  • Go 语言中的 `recover()` 函数详解
  • 医疗生态全域智能化:从技术革新到价值重塑的深度探析
  • 基于Spring Boot 3.0、ShardingSphere、PostgreSQL或达梦数据库的分库分表
  • Go语言之路————接口、泛型
  • 在Anolis OS 8上部署Elasticsearch 7.16.1与JDK 11的完整指南
  • 首页数据展示
  • keep-alive具体使用方法
  • C++多线程与锁机制
  • MySQL 在 CentOS 7 环境下的安装教程
  • 如何解决 Xcode 签名证书和 Provisioning Profile 过期问题
  • 2025年“投资新余•上海行”钢铁产业“双招双引”推介会成功举行
  • 中国人保一季度业绩“分化”:财险净利增超92%,寿险增收不增利
  • 习近平对辽宁辽阳市白塔区一饭店火灾事故作出重要指示
  • 癌症来临前,可能伪装成这几种常见病,千万别大意
  • 中国体育报关注徐梦桃、王曼昱、盛李豪等获评全国先进工作者:为建设体育强国再立新功
  • 伊朗内政部长:港口爆炸由于“疏忽”和未遵守安全规定造成