后端代码练习5--验证码案例

server/2024/10/18 5:43:50/

        我们日常生活中,在进行应用程序注册或者登录的时候,出于安全性的考虑,我们都会被进行一项验证的操作,即通过网页给我们的图片进行一些列的操作,最终完成对我们身份的验证并给我们这些用户返回验证码,让我们来完成注册或者登录;

        今天我们来学习验证码案例;

1. 需求

        界面如下图所示:

         页面能有一下的显示效果:

        1、页面生成验证码

        2、输入验证码,点击提交,验证用户输入的验证码是否正确,正确则进行页面跳转

2. 准备工作

        创建Spring Boot项目,引入SpringMVC的依赖包,把前端页面放在项目中:

        index1.html代码:

<!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="/admin/captcha" 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', '/admin/captcha?dt=' + new Date().getTime()).fadeIn();});$("#checkCaptcha").click(function () {alert("验证码校验");});</script>
</body></html>

          success1.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>

 

3. 约定前后端交互接口

3.1 需求分析

        后端生成验证码图片,发送到前端页面,前端根据图片输入内容,点击提交,校验验证码是否正确,正确切换登录页面,错误提示验证码错误。

        后端需要提供两个服务:

1、生成验证码图片,返回给前端

2、校验验证码是否正确。

3.2 接口定义

1、生成验证码

请求URL:/captcha/getCaptcha

param:无

return:图片(响应)

2、校验验证码

请求URL:/captcha/check

param:inputCode

return:true / false(响应)

   3.3 Hutool工具介绍

        验证码的实现,是使用Hutool提供的小工具来实现的。Hutool是一个Java工具包类库,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util(静态)工具类。 Hutool是一个小而全的Java工具类库,通过静态方法进行封装,降低相关API的学习成本,提高工作效率;

Hutool官方:https://hutool.cn/参考文档:简介 | Hutool 

3.3.1 引入依赖

        在官方文档中,官方建议使用下面这个版本,如图:

         我们使用这个版本,可以在这里直接复制,粘贴到我们项目的pom.xml文件中,也可以去maven的中央仓库找,如图:中央仓库地址:https://mvnrepository.com/

        进入中央仓库,搜索hutool,选择:

        选择合适版本的依赖:

          当前是5.8.16版本,因为只需要使用验证码功能,所以就只用含有验证码功能的,不选all全部,在pom.xml文件添加下面内容: 

java">		<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-captcha --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-captcha</artifactId><version>5.8.16</version></dependency>

3.3.2 测试使用Hutool生成验证码

        在test包(这个包也是专门给后端人员进行测试代码用的)路径下创建CaptchaTest类,进行测试,使用官方文档给我们提供的代码:

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

        运行main方法后发现,在目的位置下,有两个图片,如图:

控制台输出内容:

4. 实现服务器端代码

4.1 后端代码

        yml配置内容:

java">captcha:width: 200height: 100session:key: captcha_session_keydate: captcha_session_date

        把配置项挪到配置文件中,把生成的验证码存储在Session中,校验时使用配置项。 

        验证码配置项对应的Java对象:

java">@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;}
}

        Controller代码:

java">@RequestMapping("/captcha")
@RestController
public class CaptchaController {@Autowiredprivate CaptchaProperties captchaProperties;public static final long session_valid_timeout = 60 * 1000;//1分钟//验证码页面@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());response.getOutputStream().close();} catch (IOException e) {throw new RuntimeException(e);}}//校验验证码@RequestMapping("/check")public Boolean check(String inputCode, HttpSession session) {//验证码生成的内容,和用户输入的内容进行比较if(!StringUtils.hasLength(inputCode)) {return false;}//从Session获取信息String saveCode = (String)session.getAttribute(captchaProperties.getSession().getKey());Date saveDate = (Date)session.getAttribute(captchaProperties.getSession().getDate());if(inputCode.equals(saveCode)) {//如果时间超过1分钟,验证码就失效if(saveDate != null && (System.currentTimeMillis() - saveDate.getTime()) < session_valid_timeout) {return true;}}return false;}
}

        代码简单流程: 

           这里使用到了读取配置文件的内容,因为验证码的宽度、长度、Session的key和date字符串也是不变的,所以可以把它们放到配置文件中。先定义它们的值,然后创建对象,把配置文件放到对象中,再使用@Autowired注解,CaptchaController类就可以读取到配置文件中的内容了。

        验证码的界面的设计,由于session里面要存储正确的验证码,如果有多个用户同时登录,就要考虑多线程的,不同的用户返回的验证码也要不同,也符合Session的要求,所以我们使用Session存储用户页面的验证码内容,虽然设置字符串的参数一样,但每个用户在服务器存储的Session是不同的对象,会根据SessionId对应不同用户的Session,而验证码也在Session,刚好也可以传给客户端这边。

        验证码图片是以流的方式传给用户界面,要记得close关掉文件描述符表,不然资源可能会随着请求的增多,把文件描述符表使用完。

        因为我们平时使用的验证码都有时间限制,所以我们设定闲置时间为当前时间减去session设置的时间,因为当验证码向用户传输过去的时候,我们的session才成功创立;我们当前设置时间为1min;

        我们还要设置返回类型,和禁止缓存,因为验证码不能一直都是一样的,为了防止浏览器缓存,就要设置一下。

4.2 前端代码

java"><!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 = "success1.html";} else {alert("验证码错误或过期");}}});});</script>
</body></html>

5. 运行测试

        浏览器访问

验证成功:

验证失败:

ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!
————————————————

电子签名:上嘉路
 

 

 


http://www.ppmy.cn/server/103960.html

相关文章

精选这五款热门好用的骨传导耳机,帮你避免踩坑的麻烦!

相信大家都已经深有体会&#xff0c;拿那种常规的入耳式无线蓝牙耳机来做运动耳机&#xff0c;很难满足运动需要。如果选择前两年流行的颈挂式无线运动蓝牙耳机&#xff0c;虽然简单轻巧&#xff0c;但也是入耳式设计&#xff0c;长时间佩戴耳朵不舒服。这样看来&#xff0c;运…

ChatGPT丨国自然基金项目撰写技巧

随着社会经济发展和科技进步&#xff0c;基金项目对创新性的要求越来越高。申请人需要提出独特且有前瞻性的研究问题&#xff0c;具备突破性的科学思路和方法。因此&#xff0c;基金项目申请往往需要进行跨学科的技术融合。申请人需要与不同领域结合&#xff0c;形成多学科交叉…

《QT从基础到进阶·七十三》Qt+C++开发一个python编译器,能够编写,运行python程序

1、概述 源码放在文章末尾 该项目利用QtC实现了一个简易的python编译器&#xff0c;类似pycharm或vsCode这样的编译器&#xff0c;该python编译器支持如下功能&#xff1a; &#xff08;1&#xff09;支持编写python程序 &#xff08;2&#xff09;编写代码时有代码补全提示 &…

鸿蒙Harmony开发实战—ArkTS语句

语句 If语句 if语句用于需要根据逻辑条件执行不同语句的场景。当逻辑条件为真时&#xff0c;执行对应的一组语句&#xff0c;否则执行另一组语句&#xff08;如果有的话&#xff09;。 else部分也可能包含if语句。 if语句如下所示&#xff1a; if (condition1) {// 语句1 }…

裸金属服务器和裸金属云服务器:区别、优势与选择

裸金属服务器和裸金属云服务器的区别、优势与选择的分析&#xff1a; 一、区别 1. 资源独占性 - 裸金属服务器&#xff1a;提供完全独立、专属的物理服务器资源&#xff0c;不存在任何资源共享&#xff0c;确保每个用户对硬件资源的绝对占有。 - 裸金属云服务器&#xff1a;尽…

如何选择需求跟踪管理软件?8款优质推荐

本文将介绍8款需求跟踪管理软件&#xff1a;PingCode、Worktile、得帆、协作云、火山引擎、Jira、VersionOne、YouTrack。 在面对众多需求跟踪管理软件时&#xff0c;每款软件都声称能提升效率、简化流程&#xff0c;但到底哪一款才真正适合你的团队&#xff1f;为了选择合适的…

Conditional Flow Matching: Simulation-Free Dynamic Optimal Transport论文阅读笔记

Conditional Flow Matching: Simulation-Free Dynamic Optimal Transport笔记 发现问题 连续正规化流&#xff08;CNF&#xff09;是一种有吸引力的生成式建模技术&#xff0c;但在基于模拟的最大似然训练中受到了限制。 解决问题 介绍一种新的条件流匹配&#xff08;CFM)&…

【网络】HTTPS——HTTP的安全版本

1.HTTP的问题 1、使用明文通信 HTTP协议不具备给通讯内容加密的功能&#xff0c;所有使用HTTP协议通信的请求和响应的内容无法进行加密,都是使用明文发送。由于HTTP属于TCP/IP协议族的协议&#xff0c;按照TCP/IP协议族的通讯机制&#xff0c;HTTP在整个通讯线路上都存在被窃听…