《JavaEE进阶》----14.<SpringMVC配置文件实践之【验证码项目】>

news2024/9/22 1:11:29

本篇博客介绍的是Google的开源项目Kaptcha来实现的验证码。

这种是最简单的验证码。

也是很常见的一种验证码。可以去看项目结果展示。就可以明白这个项目了。

前言:

随着安全性的要求越来越高、很多项目都使用了验证码。如今验证码的形式也是有许许多多、更复杂的图形验证码和行为验证码已经成为了更流行的趋势.

验证码的实现方式有很多,网上也有比较多的插件或者工具包可以使用。

本篇博客介绍的是Google的开源项目Kaptcha来实现的。

上图就是我们要做的验证码示例:

验证码 = 验证码 + 背景图片 + 干扰项 

验证码前后端都可以做。

验证码的原理并不复杂。

项目需求:

首先我们来了解一下本篇讲解的验证码是什么样的。能达到什么效果。

1.页面生成验证码

2.输入验证码、点击提交、验证用户输入验证码是否正确、正确则进行页面跳转。不正确则继续刷新验证码、重新输入。

一、Kaptcha插件介绍

Kapycha 是Google的一个高度可配置的实用验证码生成工具。

1.1 验证码原理

验证码可以客户端生成,也可以服务器生成。对于普通的字符验证码,后端通常分两部分。

一是生成验证码内容,根据验证码内容和干扰项等生成图片,返回给客户端。

二是把验证码内容存储起来。校验时取出来进行对比。

kaptcha插件选择把验证码存储在Session里。

1.2引入依赖

首先我们要引入依赖,相当于下载好这个插件。

<dependency>
    <groupId>com.oopsguy.kaptcha</groupId>
    <artifactId>kaptcha-spring-boot-starter</artifactId>
    <version>1.0.0-beta-2</version>
</dependency>

1.3生成验证码

这个插件提供了两种方式生成验证码

1.通过代码来生成(不具体说了)

2.仅通过配置文件来生成验证码(推荐使用)

Kaptcha详细配置(简单了解一下即可)

 

也可以使用Kaptcha.items配置多个验证码生成器。

Kaptcha.items是一个Map

key为验证码生成器名称、value为验证码生成器的配置

下面是我们在yml的类型的配置文件中的配置。这里简单示例一下:

#配置Kaptcha验证码
kaptcha:
  items:
  # home captcha
    home:
      path: /home/captcha
      session:
        key: HOME_KAPTCHA_SESSION_KEY
        date: HOME_KAPTCHA_SESSION_DATE
  # admin captcha
    admin:
      path: /admin/captcha
      session:
        key: ADMIN_KAPTCHA_SESSION_KEY
        date: ADMIN_KAPTCHA_SESSION_DATE

 配置说明:

home:生成器名称

path:生成器访问路径

session:

        key:

        date:

这三个是生成验证码存储中Session中的key

配置后,可以直接访问http://XXXX:port/home/captcha即可生成验证码

如我的访问路径就是

http://127.0.0.1:1208/home/captcha

http://127.0.0.1:1208/admin/captcha

两个都可以。

当刷新浏览器,就会刷新出新的验证码。

显然我们只是能够显示出验证码。那么我们如何让验证码为我们所用。达到验证的目的呢

类似于这样。这就是我们接下来要做的工作了。

二、配合Spring MVC来使用验证码

1.创建项目,引入SpringMVC的依赖包。

2.引入kapycha依赖。相当于下载,载入这个插件

        <dependency>
            <groupId>com.oopsguy.kaptcha</groupId>
            <artifactId>kaptcha-spring-boot-starter</artifactId>
            <version>1.0.0-beta-2</version>
        </dependency>

3.使用yml配置文件 生成验证码

kaptcha: 
  border:
    enbaled: true
  image:
    height: 50
    width: 160
  text-producer:
    character:
      length: 4
    font:
      color: blue
  items:
    admin:
      path: /admin/captcha
      session:
        key: KAPTCHA_SESSION_KEY
        date: KAPTCHA_SESSION_DATE

生成的验证码效果如图所示: 

在项目中放入前端代码:前端需要约定前后端交互接口。

2.1前端代码

1.进行前端页面展示

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="captcha" 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 () {
        $.ajax({
          url: "/admin/check",
          type: "get",
          data: {
            captcha: $("#inputCaptcha").val(), //取值
          },
          success: function (result) {
            if (result) {
              location.href = "success.html";
            } else {
              alert("验证码校验错误!");
            }
          },
        });
      });
    </script>
  </body>
</html>

前后端交互的代码:

    <script>
      $("#verificationCodeImg").click(function () {
        $(this)
          .hide()
          .attr("src", "/admin/captcha?dt=" + new Date().getTime())
          .fadeIn(); //防止前端浏览器缓存
      });

      $("#checkCaptcha").click(function () {
        $.ajax({
          url: "/admin/check",
          type: "get",
          data: {
            captcha: $("#inputCaptcha").val(), //取值
          },
          success: function (result) {
            if (result) {
              location.href = "success.html";
            } else {
              alert("验证码校验错误!");
            }
          },
        });
      });
    </script>

 

前端页面展示:

2.2后端代码

后端工作

1.生成验证码、并返回验证码

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

2.2.1定义生成验证码的接口

通过get请求:/admin/captcha路径

响应图片内容。

2.2.2 校验验证码是否正确的接口

请求:/admin/check

captcha :用户输入的验证码等于图片中的验证码

响应:true/false

@RequestMapping("/admin")
@RestController
public class KaptchaController {
    private static final String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";
    private static final String KAPTCHA_SESSION_DATE = "KAPTCHA_SESSION_DATE";
    private static final long TIME_OUT = 60 * 1000; //一分钟/毫秒数

    @RequestMapping("/check")
    public boolean check(String captcha, HttpSession session){
        //判断输入的验证码是否为空
        if(!StringUtils.hasLength(captcha)){
            return false;
        }
        //获取生成的验证码
        String savedCaptcha = (String) session.getAttribute(KAPTCHA_SESSION_KEY);
        Date savedCaptchaData = (Date) session.getAttribute(KAPTCHA_SESSION_DATE);
        System.out.println(savedCaptcha);

        if(captcha.equalsIgnoreCase(savedCaptcha)){//不区分验证码的大小写进行比对
            //savedCaptchaData != null
            //在 Session 中不存在或尚未存储时,尝试读取它的值会导致空指针异常,程序会中断。
            //在后续的时间计算逻辑中可能会出现错误。...
            if(savedCaptchaData != null && System.currentTimeMillis()-savedCaptchaData.getTime() < TIME_OUT ){
                return true;
            }
        }
        return false;
    }

}

项目结果展示:

1.进入验证页面

2.输入验证码并提交,成功跳转页面到成功页面

 

3.验证码输入错误时,弹窗提示。当验证码生成后1分钟验证码会失效。此时也会弹窗报错。

 

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

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

相关文章

(有直接运行的源码)SpringBoot-MyBatis in查询 <foreach> 范围查询, 以及其他方法查询

文章目录 第一种: names入参为数组,foreach标签遍历第二种: name入参是纯字符串, 代替数据中的内容需要的工具类第三种: name入参为纯字符串, foreach标签分割遍历第四种: mysql中使用 (待补充)第五种: 存储过程和函数,以及其他数据库(待补充)源代码地址第一种: names入参为数组…

王道考研操作系统笔记(一)

虚拟内存的定义和特征&#xff1a; 基于局部性的原理&#xff0c; 在程序装入时&#xff0c;可以将程序中很快用到的部分装入内存&#xff0c;暂时用不到的数据装入外存&#xff0c;就可以让程序开始执行&#xff0c;在程序执行过程中&#xff0c;当所访问的信息不在内存的时…

以租代卖+押金原路退回系统 阿雪技术观市场策划

一、市场目标 1. 提高软件的知名度和用户使用率。 2. 促进物品的流转和租赁&#xff0c;增加用户参与度和满意度。 3. 探索新的商业模式&#xff0c;为公司带来更多的收益和发展机会。 二、实施步骤 1. 软件平台搭建 - 开发和优化市场策划软件&#xff0c;确保其功能完善…

数据库系列之GaussDB数据库中逻辑对象关系简析

初次接触openGauss或GaussDB数据库的逻辑对象&#xff0c;被其中的表空间、数据库、schema和用户之间的关系&#xff0c;以及授权管理困惑住了&#xff0c;与熟悉的MySQL数据库的逻辑对象又有明显的不同。本文旨在简要梳理下GaussDB数据库逻辑对象之间的关系&#xff0c;以加深…

【高级编程】Java IO流(上)字节流 InputStream OutputStream

文章目录 文件操作流输入流InputStream输出流OutputStream 文件操作 文件是指相关记录或放在一起的数据的集合。是一种用于存储数据的基本单位&#xff0c;它可以包含各种类型的信息&#xff0c;例如文本、图像、音频或视频。文件在计算机中通常存储在磁盘或其他存储介质上&am…

华为OD机试 - 最大相连男生数 - 矩阵(Java 2024 E卷 200分)

华为OD机试 2024E卷题库疯狂收录中&#xff0c;刷题点这里 专栏导读 本专栏收录于《华为OD机试&#xff08;JAVA&#xff09;真题&#xff08;E卷D卷A卷B卷C卷&#xff09;》。 刷的越多&#xff0c;抽中的概率越大&#xff0c;私信哪吒&#xff0c;备注华为OD&#xff0c;加…

SprinBoot+Vue健康健身追踪系统的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

基于SpringBoot+Vue社区家政服务预约平台【提供源码+答辩PPT+参考文档+项目部署】

项目技术架构&#xff1a; 该家政服务预约平台基于B/S架构&#xff0c;后端采用SpringBoot架构&#xff0c;前端采用VueElementUI技术&#xff0c;并结合MySQL数据库。该系统分为系统管理员、家政人员、雇主用户三种角色。 系统核心功能&#xff1a; 用户管理、家政人员管理…

Zenmap

Zenmap Zenmap 本身作为一款端口扫描的工具无法直接判断一台服务器是否存在具体的漏洞&#xff0c;但它可以帮助你识别服务器上的开放端口、运行的服务以及操作系统信息&#xff0c;通过这些信息&#xff0c;需要你自己凭借经验推测可能存在的漏洞&#xff0c;或者结合其他工具…

微服务CI/CD实践(六)Jenkins Docker 自动化构建部署Java微服务

微服务CI/CD实践系列&#xff1a; 微服务CI/CD实践&#xff08;一&#xff09;环境准备及虚拟机创建 微服务CI/CD实践&#xff08;二&#xff09;服务器先决准备 微服务CI/CD实践&#xff08;三&#xff09;gitlab部署及nexus3部署 微服务CI/CD实践&#xff08;四&#xff09…

log4j日志封装说明—slf4j对于log4j的日志封装-正确获取调用堆栈

日志是项目中必用的东西&#xff0c;日志产品里最普及应该就是log4j了。(logback这里暂不讨论。) 先看一下常用的log4j的用法&#xff0c;一般来说log4j都会配合slf4j或者common-logging使用&#xff0c;这里已slf4j为例。添加gradle依赖&#xff1a; dependencies { compile(l…

When is a Liability not a Liability

When is a Liability not a Liability? Textual Analysis, Dictionaries, and 10-Ks(2011) 论文阅读 文章目录 When is a Liability not a Liability? Textual Analysis, Dictionaries, and 10-Ks(2011) 论文阅读 Abstract哈佛H4N List 与 Fin-Neg如何创建词汇列表&#xff1…

声音克隆工具CosyVoice

阿里的免费声音克隆工具CosyVoice CosyVoice 是阿里通义实验室在七月初开源的一款专注于自然语音合成的语音大模型&#xff0c;它具备多语言、多音色和细腻的情感控制能力。这个系统支持中文、英文、日文、粤语和韩语五种语言的语音生成&#xff0c;并且在语音合成的效果上远超…

【python】SemEval 2014数据集 xml文件格式转换为csv+txt

笔记为自我总结整理的学习笔记&#xff0c;若有错误欢迎指出哟~ 【python】SemEval 2014数据集 xml文件格式转换为csvtxt SemEval2014简介4个子任务数据格式xml转csvxml转txt SemEval2014简介 SemEval2014&#xff0c;ABSA&#xff08; Aspect Based Sentiment Analysis&#…

Dance with Compiler - EP3 ARM64 汇编传参约定以及 restrict 汇编分析

在 ARM64 架构&#xff08;也称为 AArch64&#xff09;中&#xff0c;函数调用约定定义了寄存器如何用于传递参数和返回值。这些约定有助于实现高效的函数调用和返回。在 ARM64 的汇编中&#xff0c;寄存器传参遵循以下约定&#xff1a; 参数传递寄存器 x0 - x7: 这 8 个寄存器…

Golang | Leetcode Golang题解之第396题旋转函数

题目&#xff1a; 题解&#xff1a; func maxRotateFunction(nums []int) int {numSum : 0for _, v : range nums {numSum v}f : 0for i, num : range nums {f i * num}ans : ffor i : len(nums) - 1; i > 0; i-- {f numSum - len(nums)*nums[i]ans max(ans, f)}return…

超声波气象站

超声波气象站的设计优势包括&#xff1a; 非接触式测量&#xff1a;超声波气象站利用超声波技术进行测量&#xff0c;可以在不接触被测物体的情况下进行精确的测量。这意味着测量过程不会受到外界干扰或影响&#xff0c;提高了测量的准确性和可靠性。 多参数测量&#xff1a;超…

LVGL 控件之标签(lv_label)

目录 一、概述二、标签1、设置文本2、长模式3、文本着色4、文本选择5、内置图标6、事件7、API 函数 一、概述 标签部件由三个部分组成&#xff1a;主体背景、滚动条和所选文本&#xff1a; LV_PART_MAIN&#xff08;主体背景&#xff09;使用所有典型的背景属性和文本属性。 …

windows手工杀毒-寻找可疑进程之网络连接

上篇回顾&#xff1a;windows手工杀毒-寻找可疑进程之句柄 上篇我们简单介绍了如何通过句柄发现可疑进程&#xff0c;主要有两个方向&#xff0c;一个是通过命名句柄的名称&#xff0c;利用全局唯一的句柄名反向标识进程&#xff0c;另一个就是通过句柄查看进程占有的资…

二、线性结构及算法

文章目录 一、稀疏数组1.1 实际需求1.2 基本介绍1.3 应用实例 二、队列2.1 引入2.2 基本介绍2.3 数组模拟队列 三、链表3.1 链表介绍3.2 单链表的应用实例3.3 单链表面试题3.4 双向链表应用实例3.5 单向环形链表 四、栈4.1 基本介绍4.2 数组模拟栈4.3 链表模拟栈4.4 栈实现综合…