当前位置: 首页 > article >正文

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

本篇博客介绍的是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.kler.cn/a/302928.html

相关文章:

  • 优化时钟网络之时钟抖动
  • DevOps工程技术价值流:加速业务价值流的落地实践与深度赋能
  • LLMs 如何处理相互矛盾的指令?指令遵循优先级实验
  • 第74期 | GPTSecurity周报
  • 使用jmeter查询项目数据库信息,保存至本地txt或excel文件1108
  • 使用 Flask 和 ONLYOFFICE 实现文档在线编辑功能
  • 【聊聊AI编程必不可少的NLTK及其punkt、punkt_tab安装】
  • Python | Leetcode Python题解之第395题至少有K个重复字符的最长子串
  • WRF-LES与PALM微尺度气象大涡模拟、PALM静态数据预备、PALM驱动数据预报、PALM模拟
  • 软件交付文档
  • NAND NOR FLASH闪存产品的学习记录
  • 充电桩平台的优惠券功能如何设计
  • 【编程底层原理】Tomcat为何要打破双亲委派模式
  • 布局管理, 分割窗口, 停靠窗口, 堆栈窗口, 综合应用
  • 代码随想录算法训练营第14天|226. 翻转二叉树、101. 对称二叉树、104. 二叉树的最大深度、111. 二叉树的最小深度
  • 基于Java的建筑节能监测系统+公共建筑能耗监测系统
  • 【笔记】1.1 拉伸力-伸长(延伸)曲线和应力-应变曲线
  • QT使用相机拍照
  • 突破行业边界,构建可持续未来:2024生态系统架构创新与开放标准赋能全球业务增长
  • linux-L8.linux更改文件的拥有者
  • 解决idea git比对 contents have differences only in line separators
  • VLAN配置学习笔记
  • Redis 数据类型详解
  • 二叉排序树在实际生活应用中作用
  • 如何通过subprocess在数据采集中执行外部命令 —以微博为例
  • “勇者斗恶龙”即将上演,乐道L60剑指Model Y