验证码案例

目录

前言

一、Hutool工具介绍

1.1 Maven 

1.2 介绍

1.3 实现类 

二、验证码案例

2.1 需求

2.2 约定前后端交互接口

2.2.1 需求分析

2.2.2 接口定义

2.3 后端生成验证码

2.4 前端接收验证码图片

2.5 后端校验验证码

2.6  前端校验验证码

2.7 后端完整代码 


前言

        验证码实现方式很多,可以前端实现,也可以后端实现,网上也有比较多的插件或者工具包可以使用,咱们选择使用Hutool提供的小工具来实现。

一、Hutool工具介绍

        Hutool是一个Java工具包类库,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类。Hutool官网:https://hutool.cn/

1.1 Maven 

如果你想在项目中使用Hutool中的某个模块,在项目的pom.xml的dependencies中加入以下内容:

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-captcha</artifactId><version>5.8.22</version>
</dependency>

1.2 介绍

验证码功能位于cn.hutool.captcha包中,核心接口为ICaptcha,此接口定义了以下方法:

  • createCode 创建验证码,实现类需同时生成随机验证码字符串和验证码图片
  • getCode 获取验证码的文字内容
  • verify 验证验证码是否正确,建议忽略大小写
  • write 将验证码图片写出到目标流中

其中write方法只有一个OutputStreamICaptcha实现类可以根据这个方法封装写出到文件等方法。

AbstractCaptcha为一个ICaptcha抽象实现类,此类实现了验证码文本生成、非大小写敏感的验证、写出到流和文件等方法,通过继承此抽象类只需实现createImage方法定义图形生成规则即可。 

1.3 实现类 

LineCaptcha线段干扰的验证码

贴栗子:

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.lang.Console;public class LineCaptchaTest {public static void main(String[] args) {//定义图形验证码的长和宽LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);//图形验证码写出,可以写出到文件,也可以写出到流lineCaptcha.write("d:/line.png");//输出codeConsole.log(lineCaptcha.getCode());//验证图形验证码的有效性,返回boolean值lineCaptcha.verify("1234");//重新生成验证码lineCaptcha.createCode();lineCaptcha.write("d:/line.png");//新的验证码Console.log(lineCaptcha.getCode());//验证图形验证码的有效性,返回boolean值lineCaptcha.verify("1234");}
}

控制台截图生成的验证码:

 

在写入的路径中查看代码生成的验证码截图:

CircleCaptcha 圆圈干扰验证码 

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.CircleCaptcha;
import cn.hutool.core.lang.Console;public class CircleCaptchaTest {public static void main(String[] args) {//定义图形验证码的长、宽、验证码字符数、干扰元素个数CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(200, 100, 4, 20);//CircleCaptcha captcha = new CircleCaptcha(200, 100, 4, 20);//图形验证码写出,可以写出到文件,也可以写出到流captcha.write("d:/circle.png");//输出codeConsole.log(captcha.getCode());//验证图形验证码的有效性,返回boolean值captcha.verify("1234");}
}

 控制台截图生成的验证码:

 在写入的路径中查看代码生成的验证码截图:

ShearCaptcha 扭曲干扰验证码 

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ShearCaptcha;
import cn.hutool.core.lang.Console;public class ShearCaptchaTest {public static void main(String[] args) {//定义图形验证码的长、宽、验证码字符数、干扰线宽度ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);//ShearCaptcha captcha = new ShearCaptcha(200, 100, 4, 4);//图形验证码写出,可以写出到文件,也可以写出到流captcha.write("d:/shear.png");//输出codeConsole.log(captcha.getCode());//验证图形验证码的有效性,返回boolean值captcha.verify("1234");}
}

控制台截图生成的验证码:

在写入的路径中查看代码生成的验证码截图:

二、验证码案例

2.1 需求

需求如下:

  • 页面生成验证码
  • 输入验证码,点击提交,验证用户输入验证码是否正确,正确则进行页面跳转

2.2 约定前后端交互接口

2.2.1 需求分析

后端需要提供两个服务:

  • 生成验证码,并返回验证码
  • 校验验证码是否正确

2.2.2 接口定义

1、生成验证码:

url:/captcha/get

param:无

return:图片的内容

2、校验验证码

url:/captcha/check

param:inputCode

return:true/false

2.3 后端生成验证码

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;@RestController
@RequestMapping("/captcha")
public class CaptchaController {@RequestMapping("/get")public void getCaptcha(HttpServletResponse response) {//定义图形验证码的长和宽LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);//图像验证码写出,可以写出到文件,也可以写出到流,此处写出到流try {lineCaptcha.write(response.getOutputStream());} catch (IOException e) {throw new RuntimeException(e);}}
}

小技巧:在我们每写完一个后端代码模块时,我们可以进行测试,看是否有错误,避免后续代码量过多发生错误时不知道哪块出错。

根据后端定义的url进行测试截图:

2.4 前端接收验证码图片

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>验证码</title><style>#inputCaptcha {height: 30px;vertical-align: middle; }#verificationCodeImg{vertical-align: middle; }#checkCaptcha{height: 40px;width: 100px;}</style>
</head><body><h1>输入验证码</h1><div id="confirm"><input type="text" name="inputCaptcha" id="inputCaptcha"><img id="verificationCodeImg" src="/captcha/get" style="cursor: pointer;" title="看不清?换一张" /><input type="button" value="提交" id="checkCaptcha"></div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>$("#verificationCodeImg").click(function(){$(this).hide().attr('src', '/captcha/get?dt=' + new Date().getTime()).fadeIn();});$("#checkCaptcha").click(function () {alert("验证码校验");});</script>
</body></html>

验证前端是否有问题:

2.5 后端校验验证码

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.example.demo.model.CaptchaProperties;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;
import java.util.Date;@RestController
@RequestMapping("/captcha")
public class CaptchaController {private final static long session_valid_timeout = 60 * 1000;@Autowiredprivate CaptchaProperties captchaProperties;@RequestMapping("/check")public Boolean check(HttpSession session, String inputCode) {//验证码输入的内容和用户输入的进行比较//从session获取信息if (!StringUtils.hasLength(inputCode)) {return false;}String savedCode = (String) session.getAttribute(captchaProperties.getSession().getKey());Date saveDate = (Date) session.getAttribute(captchaProperties.getSession().getDate());if (inputCode.equalsIgnoreCase(savedCode)) {//判断验证码是否过期if (saveDate != null && System.currentTimeMillis() - saveDate.getTime() < session_valid_timeout) {return true;}return true;}return false;}
}

检查校验验证码是否存在问题:

1、先查看后端生成的验证码

2、根据校验验证的url进行验证

        首先先输入错误的验证码观察返回ture或者false,如果返回false证明验证码输入错误或者过期,否则反正true。

先输入错误的验证码1234截图:

再输入正确的验证码截图:

2.6  前端校验验证码

<!DOCTYPE html>
<html lang="en"><head><meta charset="utf-8"><title>验证码</title><style>#inputCaptcha {height: 30px;vertical-align: middle; }#verificationCodeImg{vertical-align: middle; }#checkCaptcha{height: 40px;width: 100px;}</style>
</head><body><h1>输入验证码</h1><div id="confirm"><input type="text" name="inputCaptcha" id="inputCaptcha"><img id="verificationCodeImg" src="/captcha/get" style="cursor: pointer;" title="看不清?换一张" /><input type="button" value="提交" id="checkCaptcha"></div><script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script><script>$("#verificationCodeImg").click(function(){$(this).hide().attr('src', '/captcha/get?dt=' + new Date().getTime()).fadeIn();});$("#checkCaptcha").click(function () {$.ajax({url: "/captcha/check",type: "post",data: {inputCode: $("#inputCaptcha").val()},success: function(result) {if (result) {location.href = "success.html";} else {alert("验证码错误或者过期");}}})});</script>
</body></html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>验证成功页</title>
</head>
<body><h1>验证成功</h1>
</body>
</html>

运行截图:

 

 

2.7 后端完整代码 

package com.example.demo.controller;import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.example.demo.model.CaptchaProperties;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.io.IOException;
import java.util.Date;@RestController
@RequestMapping("/captcha")
public class CaptchaController {private final static long session_valid_timeout = 60 * 1000;@Autowiredprivate CaptchaProperties captchaProperties;@RequestMapping("/get")public void getCaptcha(HttpSession session, HttpServletResponse response) {//定义图形验证码的长和宽LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());//设置缓存类型response.setContentType("image/jpeg");//禁止缓存response.setHeader("Progma", "No-cache");//图像验证码写出,可以写出到文件,也可以写出到流,此处写出到流try {lineCaptcha.write(response.getOutputStream());//存储sessionsession.setAttribute(captchaProperties.getSession().getKey(), lineCaptcha.getCode());session.setAttribute(captchaProperties.getSession().getDate(), new Date());} catch (IOException e) {throw new RuntimeException(e);}}@RequestMapping("/check")public Boolean check(HttpSession session, String inputCode) {//验证码输入的内容和用户输入的进行比较//从session获取信息if (!StringUtils.hasLength(inputCode)) {return false;}String savedCode = (String) session.getAttribute(captchaProperties.getSession().getKey());Date saveDate = (Date) session.getAttribute(captchaProperties.getSession().getDate());if (inputCode.equalsIgnoreCase(savedCode)) {//判断验证码是否过期if (saveDate != null && System.currentTimeMillis() - saveDate.getTime() < session_valid_timeout) {return true;}}return false;}
}

配置文件:

captcha:width: 200height: 100session:key: captcha_session_keydate: captcha_session_date

captcha配置:

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;@Component
@ConfigurationProperties(prefix = "captcha")
@Data
public class CaptchaProperties {private Integer width;private Integer height;private Session session;@Datapublic static class Session {private String key;private String date;}
}

 

 

 

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

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

相关文章

基于可解释性深度学习的马铃薯叶病害检测

数据集来自kaggle文章&#xff0c;代码较为简单。 import numpy as np # linear algebra import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)# Input data files are available in the read-only "../input/" directory # For example, runni…

快团团供货大团长如何查看帮卖团长的订单?

一、功能说明 可以看到团购中每个帮卖团长帮卖产生的订单 二、具体设置方法 1、小程序端如何操作&#xff1f; 在团购页面中&#xff0c;点击订单管理&#xff0c;在这里可以选择全部团长订单&#xff0c;我的团订单&#xff0c;和帮卖团长的帮卖订单。 2、PC端如何操作&am…

ssm616基于vue.js的购物商场的设计与实现+vue【已测试】

前言&#xff1a;&#x1f469;‍&#x1f4bb; 计算机行业的同仁们&#xff0c;大家好&#xff01;作为专注于Java领域多年的开发者&#xff0c;我非常理解实践案例的重要性。以下是一些我认为有助于提升你们技能的资源&#xff1a; &#x1f469;‍&#x1f4bb; SpringBoot…

【基于C++与OpenCV实现魔方图像识别和还原算法】施工总览图

文章目录 主要效果展示思维导图魔方还原算法 本系列博客长期更新&#xff0c;分为两大部分 OpenCV实现魔方六面识别 C编写科先巴二阶段还原算法实现三阶魔方的还原 主要效果展示 摄像头识别六面 3D图像构建&#xff0c;提供还原公式 动画演示还原过程 思维导图 魔方还原算法 参…

达梦8 开启物理逻辑日志对系统的影响

物理逻辑日志&#xff0c;是按照特定的格式存储的服务器的逻辑操作&#xff0c;专门用于 DBMS_LOGMNR 包挖掘获取数据库系统的历史执行语句。当开启记录物理逻辑日志的功能时&#xff0c;这部分日志内 容会被存储在重做日志文件中。 要开启物理逻辑日志的功能&#xff0c;需要…

社区物资交易互助平台的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;管理员管理&#xff0c;基础数据管理&#xff0c;论坛管理&#xff0c;公告信息管理 前台账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;论坛&#xff0c;求助留言板&#xff0c;公…

SQL Chat:从SQL到SPEAKL的数据库操作新纪元

引言 SQL Chat是一款创新的、对话式的SQL客户端工具。 它采用自然语言处理技术&#xff0c;让你能够像与人交流一样&#xff0c;通过日常对话的形式对数据库执行查询、修改、创建及删除操作 极大地简化了数据库管理流程&#xff0c;提升了数据交互的直观性和效率。 在这个框…

反AI浪潮中的新机遇:Cara艺术社区异军突起

近日,一个名为Cara的艺术社区在网络上迅速走红,其独特的反AI定位吸引了大量创意人士。在AI技术日益普及的今天,Cara社区反其道而行之,致力于打造一个无AI侵害的创作和交流环境。这一创新模式不仅赢得了艺术家的青睐,也为国内创业者提供了新的思考角度。 一、精准定位,守…

C++ list链表的使用和简单模拟实现

目录 前言 1. list的简介 2.list讲解和模拟实现 2.1 默认构造函数和push_back函数 2.2 迭代器实现 2.2.1 非const正向迭代器 2.2.2 const正向迭代器 2.2.3 反向迭代器 2.3 插入删除函数 2.3.1 insert和erase 2.3.2 push_back pop_back push_front pop_front 2.4 构…

[word] word如何清除超链接 #媒体#笔记#知识分享

word如何清除超链接 办公中&#xff0c;少不了使用word&#xff0c;这个是大家必备的软件&#xff0c;今天给大家分享下word如何清除超链接的操作办法&#xff0c;一起来学习下吧&#xff01; 1、清除所有超链接 按下组合键CtrlshiftF9&#xff0c;就可以将网上复制带有超链…

《软件定义安全》之三:用软件定义的理念做安全

第3章 用软件定义的理念做安全 1.不进则退&#xff0c;传统安全回到“石器时代” 1.1 企业业务和IT基础设施的变化 随着企业办公环境变得便利&#xff0c;以及对降低成本的天然需求&#xff0c;企业始终追求IT集成设施的性价比、灵活性、稳定性和开放性。而云计算、移动办公…

pytorch 加权CE_loss实现(语义分割中的类不平衡使用)

加权CE_loss和BCE_loss稍有不同 1.标签为long类型&#xff0c;BCE标签为float类型 2.当reduction为mean时计算每个像素点的损失的平均&#xff0c;BCE除以像素数得到平均值&#xff0c;CE除以像素对应的权重之和得到平均值。 参数配置torch.nn.CrossEntropyLoss(weightNone,…

解决Windows窗口聚焦问题

情景引入&#xff1a; 在使用副屏显示器写代码&#xff0c;主屏显示器看教程的时候&#xff0c;突然有个知识点卡住了&#xff0c;这个时候你想要按下空格让视频暂停&#xff0c;但是按下后你会发现&#xff1a;视频没有暂停&#xff0c;倒是代码界面多了个空格。。。这就不好玩…

用HTML实现拓扑面,动态4D圆环面,可手动调节,富有创新性的案例。(有源代码)

文章目录 前言一、示例二、目录结构三、index.html&#xff08;主页面&#xff09;四、main.js五、Tour4D.js六、swissgl.js七、dat.gui.min.js八、style.css 前言 如果你觉得对代码进行复制粘贴很麻烦的话&#xff0c;你可以直接将资源下载到本地。无需部署&#xff0c;直接可…

如何对stm32查看IO功能。

有些同学对于别人的开发板的资源&#xff0c;或者IO口&#xff0c;或者串口等资源不知道怎么分配。 方法1、看硬石、野火、正点原子的开发板&#xff0c;看下他们的例子&#xff0c;那个资源用什么。自己多看几个原理图&#xff0c;多看几个视频&#xff0c;做一下笔记。以后依…

【面试干货】MySQL 三种锁的级别(表级锁、行级锁和页面锁)

【面试干货】MySQL 三种锁的级别&#xff08;表级锁、行级锁和页面锁&#xff09; 1、表级锁2、行级锁3、页面锁4、总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在 MySQL 数据库中&#xff0c;锁是控制并发访问的重要机制&#xff0…

GQA,MLA之外的另一种KV Cache压缩方式:动态内存压缩(DMC)

0x0. 前言 在openreview上看到最近NV的一个KV Cache压缩工作&#xff1a;https://openreview.net/pdf?idtDRYrAkOB7 &#xff0c;感觉思路还是有一些意思的&#xff0c;所以这里就分享一下。 简单来说就是paper提出通过一种特殊的方式continue train一下原始的大模型&#x…

DS:树与二叉树的相关概念

欢迎来到Harper.Lee的学习世界&#xff01;博主主页传送门&#xff1a;Harper.Lee的博客主页想要一起进步的uu可以来后台找我哦&#xff01; 一、树的概念及其结构 1.1 树的概念亲缘关系 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限节点…

汇编:数组-寻址取数据

比例因子寻址&#xff1a; 比例因子寻址&#xff08;也称为比例缩放索引寻址或基址加变址加比例因子寻址&#xff09;是一种复杂的内存寻址方式&#xff0c;常用于数组和指针操作。它允许通过一个基址寄存器、一个变址寄存器和一个比例因子来计算内存地址。 语法 比例因子寻…

经典文献阅读之--Online Monocular Lane Mapping(使用Catmull-Rom样条曲线完成在线单目车道建图)

0. 简介 对于单目摄像头完成SLAM建图这类操作&#xff0c;对于自动驾驶行业非常重要&#xff0c;《Online Monocular Lane Mapping Using Catmull-Rom Spline》介绍了一种仅依靠单个摄像头和里程计生成基于样条的在线单目车道建图方法。我们提出的技术将车道关联过程建模为一个…