锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. SpringBoot实现图形验证码

SpringBoot实现图形验证码

0
  • 软件开发
  • 发布于 2024-07-29
  • 6 次阅读
黄健
黄健

原文链接:https://blog.csdn.net/2301_76161469/article/details/140416911

随着安全性的要求越来越高,目前许多项目中都使用了验证码,验证码也有各种类型,如 图形验证码、短信验证码、邮件验证码、人脸识别等,这些不同类型的验证码可以根据实际需求和安全性要求进行选择和应用,保护网站和用户免受恶意攻击

在本篇文章中,我们来学习图形验证码的实现

验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用 Hutool 提供的小工具实现

验证码需要实现功能:

1. 页面生成验证码,点击图片可进行刷新

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

项目创建

我们首先创建项目,并引入相关依赖

前端代码实现

接下来,我们实现两个简单的前端界面:

1. 验证码界面

2. 验证成功后跳转的界面

index.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="/captcha/getCaptcha" 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/getCaptcha?dt=' + new Date().getTime()).fadeIn();

    });

 

    $("#checkCaptcha").click(function () {

        alert("判断验证码是否正确");

    });

  </script>

</body>
</html>

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

约定前后端交互接口

需求分析

后端需要提供两个服务:

1. 生成验证码,并返回

2. 校验验证码是否正确

接口定义

1. 生成验证码

[URL]

GET /captcha/getCaptcha

[请求参数]

[响应]

{

验证码图片内容

}

2. 校验验证码是否正确

[URL]

POST /captcha/check

[请求参数]

captcha=xmad

[响应]

{

true

}

根据用户输入的验证码,校验验证码是否正确,校验成功,返回true;校验失败,返回false

Hutool工具

我们使用 Hutool 提供的小工具来实现验证码

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

Hutool是一个小而全的Java工具类库,通过静态方法的封装,降低相关API学习成本,提高效率

Hutool官网:https://hutool.cn

实现服务器端代码

引入依赖

        <dependency>

            <groupId>cn.hutool</groupId>

            <artifactId>hutool-captcha</artifactId>

            <version>5.8.26</version>

        </dependency>

由于我们只需要实现验证码相关功能,因此只需要引入验证码部分依赖

获取验证码

我们可以通过提供的指南来学习如何使用

其中提供了:线段干扰验证码、圆圈干扰验证码、扭曲干扰验证码以及自定义验证码

我们通过其提供的例子来学习:

我们在 test 中 学习验证码的生成:

@SpringBootTest

class CaptchaControllerTest {

    @Test

    void getCaptcha() {

        //定义图形验证码的长和宽

        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);

        //图形验证码写出,可以写出到文件,也可以写出到流

        lineCaptcha.write("d:/line.png");

        //输出code

        System.out.println("生成验证码:" + lineCaptcha.getCode());

    }

}

运行,观察结果:

且在D盘下成功生成验证码:

同样的,我们可以生成圆圈干扰验证码、扭曲干扰验证码等,大家可自行进行实现

接下来,我们实现验证码的生成

在实现验证码时,需要指定图片的长、宽和验证码的过期时间(也可指定验证码字符个数、干扰元素个数等),我们在 Constants 中进行定义

public class Constants {

    public static final Integer CAPTCHA_WIDTH = 100;

    public static final Integer CAPTCHA_HEIGHT = 40;

    public static final long EXPIRATION_TIME = 60 * 1000;

}

由于当用户输入验证码时,我们需要进行校验,因此,我们需要对生成的验证码进行存储,同时,需要存储验证码的生成时间,以便判断验证码是否超时

public class Constants {

    public static final Integer CAPTCHA_WIDTH = 100;

    public static final Integer CAPTCHA_HEIGHT = 40;

    public static final long EXPIRATION_TIME = 60 * 1000;

    public static final String CAPTCHA_KEY = "captcha";

    public static final String CAPTCHA_DATE = "date";

}

接下来我们来实现 CaptchaController

@RequestMapping("/captcha")

@RestController

@Slf4j

public class CaptchaController {

    /**

     * 生成验证码

     * @param session

     * @param response

     */

    @GetMapping("/getCaptcha")

    public void getCaptcha(HttpSession session, HttpServletResponse response) {

        // 定义图形验证码的长和宽

        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(Constants.CAPTCHA_WIDTH, Constants.CAPTCHA_HEIGHT);

        // 设置返回数据类型

        response.setContentType("image/jpeg");

        // 禁止使用缓存

        response.setHeader("Pragma", "No-cache");

        try {

            // 输出到页面

            lineCaptcha.write(response.getOutputStream());

            // 将 生成的验证码 和 验证码生成时间 存储到session中

            session.setAttribute(Constants.CAPTCHA_KEY, lineCaptcha.getCode());

            session.setAttribute(Constants.CAPTCHA_DATE, new Date());

            // 关闭流

            response.getOutputStream().close();

        } catch (IOException e) {

            throw new RuntimeException(e);

        }

    }

}

运行程序,此时成功生成验证码 

验证码校验

    /**
     * 验证码校验
     * @param captcha
     * @param session
     * @return
     */
    @PostMapping("/check")
    public boolean checkCaptcha(String captcha, HttpSession session) {
        log.info("接收到验证码: {}", captcha);
        // 参数校验
        if(!StringUtils.hasLength(captcha)) {
            return false;
        }
        // 获取存储的验证码和生成时间
        String code = (String) session.getAttribute(Constants.CAPTCHA_KEY);
        Date createTime = (Date) session.getAttribute(Constants.CAPTCHA_DATE);
        // 判断验证码是否正确(验证码一般忽略大小写)
        if(captcha.equalsIgnoreCase(code)) {
            // 判断验证码是否过时
            if(createTime == null || System.currentTimeMillis() - createTime.getTime() < Constants.EXPIRATION_TIME) {
                return true;
            }
            return false;
        }
        return false;
    }

将用户输入的验证码与存储在 session 中的验证码进行对比,判断其是否相同,若相同且在1min内,则验证成功

在这里,我们就不对其进行测试了,在调整前端代码后,一起进行测试

调整前端代码

接下来,我们修改 index.html

  <script>

    

    $("#verificationCodeImg").click(function(){

      $(this).hide().attr('src', '/captcha/getCaptcha?dt=' + new Date().getTime()).fadeIn();

    });

 

    $("#checkCaptcha").click(function () {

        $.ajax({

          url: "/captcha/check",

          type: "post",

          data: {

            captcha: $("#inputCaptcha").val()

          },

          success: function(result) {

            if(result) {

              location.href = "success.html";

            }else {

              alert("验证码错误或已超时");

            }

          }

        })

    });

  </script>

再次运行程序,此时输入验证码进行验证:

验证成功:

验证失败:

标签: #软件开发 1171 #JAVA 991 #新手必读 21
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.