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

news2024/9/20 22:53:03

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

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

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文件添加下面内容: 

		<!-- 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类,进行测试,使用官方文档给我们提供的代码:

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");
        //输出code
        Console.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配置内容:

captcha:
  width: 200
  height: 100
  session:
    key: captcha_session_key
    date: captcha_session_date

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

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

@Component
@ConfigurationProperties(prefix = "captcha")
@Data
public class CaptchaProperties {
    private Integer width;
    private Integer height;
    private Session session;
 
    @Data
    public static class Session {
        private String key;
        private String date;
    }
}

        Controller代码:

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @Autowired
    private 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());
            //存储Session
            session.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 前端代码

<!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.coloradmin.cn/o/2073169.html

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

相关文章

C语言-有两个磁盘文件A和B,各存放一行字母,今要求把这两个文件的信息合并(按字母顺序排列),输出到一个新文件C中去-深度代码解析

1、题目要求 有两个磁盘文件A和B&#xff0c;各存放一行字母&#xff0c;今要求把这两个文件的信息合并&#xff08;按字母顺序排列&#xff09;&#xff0c;输出到一个新文件C中去 2、准备工作 问题1&#xff1a;为什么不需要手动创建C.txt文件&#xff1f; 答&#xff1a;根…

技术分享-商城篇-订单模块-取消/收货功能(十六)

前言 再上一篇文章技术分享-商城篇-用户订单管理&#xff08;十五) 中&#xff0c;订单模块用户操作含有&#xff1a;取消订单、去支付、确认收货、删除订单、查看详情、去退款、查看物流、再次购买等业务操作&#xff0c;以上的每一个操作&#xff0c;都是对应不同的业务和状…

AudioNotes -将音频内容转 markdown

文章目录 一、关于 AudioNotes效果展示音视频识别和整理与音视频内容对话 二、使用方法1、安装 Ollama2、拉取模型3、部署服务3.1 Docker部署&#xff08;推荐&#xff09;&#x1f433;3.2 本地部署 &#x1f4e6; 一、关于 AudioNotes AudioNotes 能够快速提取音视频的内容&…

贪心处理任务(华为od机考题)

一、题目 1.原题 在某个项目中有多个任务&#xff08;用 tasks 数组表示&#xff09;需要您进行处理&#xff0c; 其中 tasks[i] [si, ei]&#xff0c; 你可以在 si < day < ei 中的任意一天处理该任务。 请返回你可以处理的最大任务数。 注&#xff1a;一天可以完成一…

硬件面试经典 100 题(81~90)题

81、请问下图电路中二极管 D1、D2 有什么作用&#xff1f; 在 Vi 输入电压接近于零时&#xff0c;D1、D2 给三极管 T1、T2 提供偏置电压&#xff0c;使 T1、T2 维持导通&#xff0c;以消除交越失真。 陈氏解释 这道题参见&#xff1a;硬件面试经典 100 题&#xff08;51~70 题…

【学习笔记】STM32F407探索者HAL库开发(三)IO分配

【学习笔记】STM32F407探索者HAL库开发&#xff08;三&#xff09;IO分配 1 STM32F407 IO资源分配表2 STM32F407ZGT6 引脚定义3 IO分配的重要性3.1 硬件设计优化3.2 软件编程3.3 系统性能提升 4 F1/F7/H7芯片的IO分配差异4.1 引脚数量和分组4.2 功能模式4.2.1 输入模式4.2.2 输…

Kubernetes 外部 etcd 集群的快速 Docker Compose 部署指南

一、背景 在高可用 Kubernetes 部署中&#xff0c;需要单独部署外部 etcd 集群&#xff0c;而不是使用 kubeadm 默认在 master 节点上部署的 etcd。以下是关于这一配置场景的详细记录。 二、etcd简介 etcd 是一个高可用的分布式键值存储系统&#xff0c;主要用于存储和管理配…

使用Qt+Visual Stuidio写一个简单的音乐播放器(1)

1.使用QMediaPlayer播放音乐 第三步:在代码头部加上: #include <QtMultimedia/QMediaPlayer> // VS向.pro文件添加代码的方式 #pragma execution_character_set("utf-8") // qt支持显示中文 QMediaPlayer类是一个高级媒体播放类。它可以用来播放歌曲、电…

leetcode 893. Groups of Special-Equivalent Strings

原题链接 You are given an array of strings of the same length words. In one move, you can swap any two even indexed characters or any two odd indexed characters of a string words[i]. Two strings words[i] and words[j] are special-equivalent if after any …

力扣: 设计链表

文章目录 需求代码结尾 需求 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 p…

Java 的数组详解

数组的定义 数组是相同类型数据的有序集合 数组描述的是相同类型的若干个数据&#xff0c;按照一定的先后次序排列组合而成 其中&#xff0c;每一个数据称作一个数组元素&#xff0c;每个数组元素可以通过一个下标(编号、标记)来访问它&#xff0c;下标是从 0 开始的&#xf…

100套动画PPT模版分享

100套动画PPT模板 目录下载链接 目录 下载链接 「动画模板」链接&#xff1a;https://pan.quark.cn/s/73ea2523f198 点击下载

中小型企业如何管理文档?8款工具来帮你

文章介绍了以下几个工具&#xff1a;PingCode、Worktile、氚云、泛微、中通天鸿、Tower、知因智慧、SharePoint。 在中小型互联网企业中&#xff0c;文档知识库的管理常常让人头疼。团队成员散布在不同的地点&#xff0c;文档分散在各种工具中&#xff0c;查找信息变得异常困难…

Linux启动流程和Systemd特性

文章目录 内核设计流派linux启动流程1.硬件加电自检2.启动加载器bootloader3.加载kernel4.init初始化5.用户终端启动 systemdsystemd特性systemd的unitunit配置文件 systemctl管理系统服务service unit服务状态 service unit文件格式Unit段Service段Install段 内核设计流派 1.…

资源第二篇:bundle 的config.json 文件内容的解析

简介 本篇文章主要是对bundle包的核心文件config.json 的分析。config.json记录着整个bundle包的具体信息&#xff0c;并通过config.json 去解析整个bundle包。 bundle 目录下的文件结构 import 存放所有的json。场景、预制体、texture2D配置等jsonnative 存放所有的实际资源…

分子属性梯度引导的3D分子生成扩散模型 TAGMOL - 评测

TAGMoL 是一个基于分子属性条件引导扩散的 3D 分子生成模型&#xff0c;适合在给定靶标蛋白质的情况下&#xff0c;可以生成一系列满足目标特性&#xff08;分子属性&#xff0c;binding affinity&#xff09;的候选分子。 一、背景介绍 TAGMoL 来源于新德里 Molecule AI, 以及…

ESP32 出现 failed to load RF 报错

前言 个人邮箱&#xff1a;zhangyixu02gmail.com 正文 周五我测试程序没有问题&#xff0c;板子放在桌子上就没动过了。周一过来的时候&#xff0c;重新烧录程序&#xff0c;就发现出现如下报错。最终发现是电池过放导致电池损坏功率不够&#xff0c;因此 RF 无法启动&#…

探寻少儿自闭症的解决之道

自闭症&#xff0c;又称孤独症谱系障碍&#xff0c;是一种广泛性发育障碍&#xff0c;给无数家庭带来了沉重的负担。然而&#xff0c;随着科学技术的不断进步和人们对自闭症认识的逐步深入&#xff0c;越来越多的方法和途径正在被探索出来&#xff0c;为自闭症的解决带来了希望…

RocketMQ 与 Spring Cloud Stream之事务消息配置

1 引言 RocketMQ的事务消息设计是为了解决分布式系统中数据一致性的问题。在分布式系统中&#xff0c;由于数据可能分布在不同的服务或节点上&#xff0c;因此需要一种机制来确保数据的最终一致性。事务消息通过引入本地事务和消息状态的关联&#xff0c;确保了消息的发送与本…

【什么是“Binary“二进制文件?】

“Binary”二进制文件是计算机文件的一种形式。部件文件是开发人员编写的源代码文件&#xff0c;还未被编译成可执行的机器代码&#xff0c;通常具有如.c、.cpp、.java 等扩展名。对象文件是部件文件经过编译器编译生成的中间文件&#xff0c;包含了部件文件的机器代码和符号表…