Java使用Hutool工具类轻松生成验证码

👩🏽‍💻个人主页:阿木木AEcru

🔥 系列专栏:《Docker容器化部署系列》 《Java每日面筋》

💹每一次技术突破,都是对自我能力的挑战和超越。

目录

    • 一、效果展示
      • 1.1 扭曲干扰的验证码
      • 1.2 线条干扰的验证码
      • 1.3 圆圈干扰的验证码
    • 二、验证码应用场景
      • 2.1 注册验证
      • 2.2 登录保护
      • 2.3 重置密码
      • 2.4 防止恶意行为
      • 2.5 活动秒杀
      • 2.6 数据保护
      • 2.7 交易安全
    • 三、Hutool工具类实现验证码生成
      • 3.1 引入依赖
      • 3.2 核心代码
      • 3.3 最简单实现方式
    • 四、设置背景颜色的坑
    • 五、结尾

一、效果展示

话不多说,先来看看效果图 ps:默认生成的背景颜色为白色的,这里我修改为了淡黄色(设置背景颜色这里有个坑,后面会讲到)

1.1 扭曲干扰的验证码

1.2 线条干扰的验证码

1.3 圆圈干扰的验证码

二、验证码应用场景

验证码是一种广泛应用于网络服务中的安全机制,用于验证用户身份,防止恶意软件和自动化脚本的滥用。以下是对验证码应用场景的详细阐述,包括不同场景下验证码的使用目的和实例说明。

2.1 注册验证

在用户注册账户时,验证码用于确保注册信息的真实性,防止恶意注册和自动化脚本的滥用。例如,在用户注册时,需要验证用户提供的手机号码是否有效,以防止注册时提供虚假或错误的手机号码。企业可以通过发送短信验证码来验证用户提供的手机号码。

2.2 登录保护

登录时使用验证码可以防止自动化工具尝试破解用户密码。在用户输入用户名或登录密码错误超过设定次数时,图形验证码出现,用以判断是否是机器人在测试数字密码,这时候就用图形验证来挡掉机器的攻击。

2.3 重置密码

当用户忘记密码时,验证码用于验证用户身份,确保密码重置请求的合法性。在重设密码流程里也需要输入验证码,图形验证码可视作后续步骤的触发,二者存在顺序关联性。

2.4 防止恶意行为

验证码用于防止恶意用户在平台上的刷单、刷票、恶意灌水等行为。例如,在论坛、投票等场景中,验证码有效抵御自动机刷赞和水军刷帖。

2.5 活动秒杀

在抢购、秒杀等活动中,验证码可以防止自动化脚本批量刷取奖励,保证活动的公平性。羊毛党频繁刷取奖励,导致真实用户无法获取奖励,验证码适用于抢购、秒杀、优惠券等活动场景。

2.6 数据保护

验证码用于保护网站内容和数据不被恶意爬虫爬取。例如,验证码适用于公告栏、论坛等内容网站,有效抵御自动机、爬虫盗取网页内容和数据。

2.7 交易安全

在进行金融交易或敏感操作时,验证码用于增强交易的安全性。例如,在线银行网站在用户进行转账操作时,可能会要求输入验证码来验证用户身份。

三、Hutool工具类实现验证码生成

3.1 引入依赖

<!--hutool工具包-->
<dependency>
	<groupId>cn.hutool</groupId>
	<artifactId>hutool-all</artifactId>
	<version>5.7.15</version>
</dependency

3.2 核心代码


@Slf4j
@RestController
@RequestMapping("/verify/code")
public class VerifyCodeController {

    //获取扭曲干扰的验证码
    @GetMapping("/createShearCaptcha")
    public void getShearCaptcha(HttpServletResponse response)
    {

        //定义图形验证码的长、宽、验证码字符数、干扰线宽度
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(150, 50,4,3);
        //设置背景颜色
        shearCaptcha.setBackground(new Color(249, 251, 220));
        //生成四位验证码
        String code = RandomUtil.randomNumbers(4);
        //生成验证码图片
        Image image = shearCaptcha.createImage(code);
        //返回验证码信息
        responseCode(response, code, image);
    }

    //获取线条干扰的验证码
    @GetMapping("/createLineCaptcha")
    public void getLineCaptcha(HttpServletResponse response)
    {

        //定义图形验证码的长、宽、验证码位数、干扰线数量
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(150, 50,4,80);
        //设置背景颜色
        lineCaptcha.setBackground(new Color(249, 251, 220));
        //生成四位验证码
        String code = RandomUtil.randomNumbers(4);
        Image image = lineCaptcha.createImage(code);
        //返回验证码信息
        responseCode(response, code, image);
    }

    //获取圆圈干扰的验证码
    @GetMapping("/createCircleCaptcha")
    public void getCircleCaptcha(HttpServletResponse response)
    {

        //定义图形验证码的长、宽、验证码位数、干扰圈圈数量
        CircleCaptcha circleCaptcha = CaptchaUtil.createCircleCaptcha(150, 50,4,30);
        //设置背景颜色
        circleCaptcha.setBackground(new Color(249, 251, 220));
        //生成四位验证码
        String code = RandomUtil.randomNumbers(4);
        Image image = circleCaptcha.createImage(code);
        //返回验证码信息
        responseCode(response, code, image);
    }




    private static void responseCode(HttpServletResponse response, String code, Image image) {
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        String uuidStr = UUID.randomUUID().toString().replace("-", "");
        log.info("生成验证码 uuidStr:{} ,code:{}",uuidStr, code);
        response.setHeader("verifyCodeUuid",uuidStr);
        try {
            BufferedImage bufferedImage = toBufferedImage(image);
            // 创建一个ByteArrayOutputStream,用于存储图片数据
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            // 写入图片数据到ByteArrayOutputStream
            ImageIO.write(bufferedImage, "jpeg", baos);
            // 将ByteArrayOutputStream转换为ByteArrayInputStream
            byte[] imageInBytes = baos.toByteArray();
            //输出
            IoUtil.write(response.getOutputStream(), true, imageInBytes);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

在这里响应的时候,我在请求头中加了个verifyCodeUuid (验证码唯一标识), 是用于后续 校验验证码使用的,可以将验证码存在redis ,存储的key的话可以使用 【前缀+请求ip+verifyCodeUuid 】 形式来进行存储,后续获取校验的时候也是一样的key,前端就需要将verifyCodeUuid 和用户输入的验证码一并传过来。这是一种简单的实现,具体 实现还需看具体业务,这里供参考。

3.3 最简单实现方式


    @GetMapping("/createShearCaptchaV2")
    public void getShearCaptchaV2(HttpServletResponse response)
    {
        //定义图形验证码的长、宽、验证码字符数、干扰线宽度
        ShearCaptcha shearCaptcha = CaptchaUtil.createShearCaptcha(150, 50,4,3);
        response.setContentType("image/jpeg");
        response.setHeader("Pragma", "no-cache");
        response.setHeader("Cache-Control", "no-cache");
        String uuidStr = UUID.randomUUID().toString().replace("-", "");
        log.info("生成验证码 uuidStr:{} ,code:{}",uuidStr, shearCaptcha.getCode());
        response.setHeader("verifyCodeUuid",uuidStr);
        try {
            //输出
            shearCaptcha.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

这里使用了默认的样式,背景色为白色。

四、设置背景颜色的坑

一开始,我是使用了3.3中的方式来返回验证码,但是需求背景颜色是需要灰色的,然后我就在3.3的基础上加上了

shearCaptcha.setBackground(new Color(233, 233, 233));

然后生成出来的图形还是白色的,就很纳闷,于是我就点进去了原码看了一下。

然后就发现 这个传输的对象是在首次创建验证码的时候初始化的,后面设置背景颜色的时候也不会去给它重新赋值, 就导致了加上背景颜色设置后也不生效的问题。

五、结尾

感谢观看至此,希望该文章能够帮助到您提升知识和技能。如果您喜欢我的内容,请不要忘记点赞和分享哦!👍

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

使用pytorch构建ResNet50模型训练猫狗数据集

数据集 1.导包 import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader from torchvision import datasets, transforms, models import numpy as np import matplotlib.pyplot as plt import os from tqdm.auto import t…

java期末突击

目录 1. 快速入门 2. 类 3. 成员方法 4. 构造器 5. 单例模式 6. 继承 7. 抽象类 8. 多线程&#xff08;Thread与Runnable&#xff09; 1. 快速入门 public class Hello {public static void main(String[] args){System.out.println("Hello,World&q…

开源项目的 README.md 这样写,hr 看了都心动

大家好&#xff0c;我是南城余。 最近在搞项目的开源 README.md 时&#xff0c;看到有的大佬的 README.md 前面都会有 badge 标识和多彩的 tag 标签。都看着超级高级&#xff0c;就想着也来实践下。 今天一篇文章带着大家个性化你的 README.md。如下图片&#xff1a; 这里我先…

【Linux】进程池

大致草稿 思维导图 学习目标 一、进程池的代码编写顺序 在进程池中&#xff0c;我们要创建多个子进程&#xff0c;并且对多个子进程和父进程建立管道的关系&#xff0c;确保父进程和子进程之间可以进行相互通信。 父进程就是master&#xff0c;而子进程就是work/slaver。大致…

低代码平台如何革新客户管理

引言 在当今快节奏的商业环境中&#xff0c;企业对于客户管理的需求日益增长。同时&#xff0c;随着技术的不断发展&#xff0c;低代码开发作为一种创新的软件开发方法正在逐渐崭露头角。低代码开发为企业提供了一种更快速、更灵活的方式来构建应用程序&#xff0c;使得传统的软…

烧脑的逻辑图又来了,精力绝对不是花费在做图上。

逻辑图设计之所以比较耗费精力&#xff0c;主要是因为它需要进行深入的思考和分析&#xff0c;以确保设计的逻辑正确、完整和可行。以下是一些可能导致逻辑图设计耗费精力的原因&#xff1a; 复杂性&#xff1a;逻辑图设计通常涉及到复杂的业务流程和系统架构。设计师需要理解各…

04-树5 Root of AVL Tree(浙大数据结构PTA习题)

04-树5 Root of AVL Tree 分数 25 作者 陈越 单位 浙江大学 An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more th…

VMware虚拟机安装Ubuntu-Server版教程(超详细)

目录 1. 下载2. 安装 VMware3. 安装 Ubuntu3.1 新建虚拟机3.2 安装操作系统 4. SSH方式连接操作系统4.1 好用的SSH工具下载&#xff1a;4.2 测试SSH连接 5. 开启root用户登录5.1 设置root用户密码5.2 传统方式切换root用户5.3 直接用root用户登录5.4 SSH启用root用户登录 6. 安…

Kali 我来了

Kali 我来了 1、官网下载2、修改密码3、开启SSH远程登录服务4、关闭kali图形化界面 1、官网下载 官方链接: https://www.kali.org/ 下载链接: https://cdimage.kali.org/kali-2024.1/kali-linux-2024.1-vmware-amd64.7z 解压后 直接导入 VmWare 就可使用可爱的小 Kali 了。 …

太阳能智能农业气象站:创新科技引领现代农业革命

TH-NQ14在科技日新月异的今天&#xff0c;现代农业正迎来一场由智能化、精准化、绿色化驱动的深刻变革。太阳能智能农业气象站作为这场变革的先锋力量&#xff0c;以其独特的优势和强大的功能&#xff0c;为现代农业的发展注入了新的活力&#xff0c;并引领着农业生产的未来趋势…

el-date-picker的使用,及解决切换type时面板样式错乱问题

这里选择器的类型可以选择日月年和时间范围&#xff0c;根据类型不同&#xff0c;el-date-picker的面板也展示不同&#xff0c;但是会出现el-date-picker错位&#xff0c;或者面板位置和层级等问题。 源代码&#xff1a; <el-selectv-model"dateType"placeholder&…

【漏洞复现】Check Point 安全网关任意文件读取漏洞(CVE-2024-24919)

0x01 产品简介 Check Point Security Gateways 是 Check Point Sofware 提供的一系列 网络安全Q解决方案。这些解决方案包括下一代防火墙(NGFW)、数据中心安全网关和 A1驱动的量子网关&#xff0c;旨在为企业提供针对复杂网络威胁的先进防护。它们通过集成的威胁防护、统的安全…

微信小程序 npm构建+vant-weaap安装

微信小程序&#xff1a;工具-npm构建 报错 解决&#xff1a; 1、新建miniprogram文件后&#xff0c;直接进入到miniprogram目录&#xff0c;再次执行下面两个命令&#xff0c;然后再构建npm成功 npm init -y npm install express&#xff08;Node js后端Express开发&#xff…

初出茅庐的小李博客之使用立创开发板(ESP32)连接到EMQX Platform【MQTT TLS/SSL 端口连接】

介绍 手上有一块立创开发板&#xff0c;本着不吃灰的原则把它用起来&#xff0c;今天就来用它来连接上自己部署的MQTT服务器进行数据通信。 硬件&#xff1a;立创开发板 开发环境&#xff1a;Arduino IDE Win11 MQTT 平台&#xff1a;EMQX Platform 立创开发板介绍&#xff1…

ChatGPT AI专题资料合集【65GB】

介绍 ChatGPT & AI专题资料合集【65GB】 &#x1f381;【七七云享】资源仓库&#xff0c;海量资源&#xff0c;无偿分享√

OSError: [Errno 117] Structure needs cleaning

一 问题描述 OSError: [Errno 117] Structure needs cleaning: /tmp/pymp-wafeatri 我重新使用SSH登录也会提示这个类似问题 二 解决方法 2.1 尝试删除报错的文件 &#xff08;想直接看最终解决方法的可忽略此处&#xff09; sudo rm -rf /tmp/pymp-wafeatri 此种方法只能保证…

手机怎么投屏?值得收藏的5个投屏软件(2024全新)

在大屏幕上观看自己喜欢的电影、电视节目和其他媒体节目总是一种很棒的体验。因此&#xff0c;如果你正在寻找通过无线网络或USB数据线在windows或mac电脑或笔记本电脑上屏幕镜像、投屏到电脑显示屏上的指南&#xff0c;那么可以花3分钟时间往下看看。在本文中&#xff0c;小编…

现在,所有人都能免费用GPT-4o了!

OpenAI今日官宣&#xff0c;ChatGPT正式向所有用户免费开放&#xff01;所有用户均可以访问定制化GPT、分析图表、询问有关照片的问题以及5月初GPT-4o添加的其他功能。 OpenAI今天在X上发布推文&#xff1a; 「所有ChatGPT免费用户现在都可以使用浏览、视觉、数据分析、文件上…

CSS+Canvas绘制最美星空(一闪一闪亮晶晶效果+流星划过)

1.效果 2.代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><style>body,html {margin: 0;padding: 0;ov…

tree2retriever:面向RAG场景的递归摘要树检索器实现

tree2retriever 面向RAG场景的递归摘要树检索器实现 Recursive Abstractive Processing for Tree-Organized Retrieval Github:https://github.com/yanqiangmiffy/tree2retriever Example import logging import picklefrom tree2retriever.cluster_tree_builder import Clus…