SpringBoot实现图形验证码的操作方法

 更新时间:2024年07月18日 10:58:21   作者:楠枬  
随着安全性的要求越来越高,目前许多项目中都使用了验证码,验证码也有各种类型,如 图形验证码、短信验证码、邮件验证码、人脸识别等,本文给大家介绍SpringBoot实现图形验证码的方法,感兴趣的朋友跟随小编一起看看吧

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

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

验证码的实现方式有很多,可以由前端实现,也可以由后端进行实现,也有很多的插件和工具包可以使用,在这里,我们使用 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>

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

验证成功:

验证失败:

到此这篇关于SpringBoot实现图形验证码的文章就介绍到这了,更多相关SpringBoot图形验证码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 浅析Java 9 Optional API 新增方法

    浅析Java 9 Optional API 新增方法

    本文我们介绍了Java 9 Optional Api新增的三个方法。or方法在Optional为空时返回Optional对象。 ifPresentOrElse()在值存在时执行Consumer参数,反之执行另一个参数回调参数。感兴趣的朋友跟随小编一起看看吧
    2019-12-12
  • Java @Scheduled定时器用法解析

    Java @Scheduled定时器用法解析

    这篇文章主要介绍了Java @Scheduled定时器用法解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • Java NIO Buffer实现原理详解

    Java NIO Buffer实现原理详解

    本篇文章主要对NIO核心三件套:缓冲区(Buffer)、选择器 (Selector)和通道(Channel),其中之一的缓冲区Buffer实现原理的学习总结。感兴趣的小伙伴可以了解一下
    2021-11-11
  • SpringBoot项目中定时器的实现示例

    SpringBoot项目中定时器的实现示例

    在Spring Boot项目中,你可以使用Spring框架提供的@Scheduled注解来编写定时任务,本文就来介绍一下SpringBoot项目中定时器的实现,感兴趣的可以了解一下
    2023-11-11
  • SpringMVC实现上传下载文件

    SpringMVC实现上传下载文件

    这篇文章主要为大家详细介绍了SpringMVC实现上传下载文件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-09-09
  • 使用ftpClient下载ftp上所有文件解析

    使用ftpClient下载ftp上所有文件解析

    最近项目需要写个小功能,需求就是实时下载ftp指定文件夹下的所有文件(包括子目录)到本地文件夹中,保留文件到目录路径不变。今天小编给大家分享使用ftpClient下载ftp上所有文件的方法,需要的的朋友参考下吧
    2017-04-04
  • Java简单使用EasyExcel操作读写excel的步骤与要点

    Java简单使用EasyExcel操作读写excel的步骤与要点

    相信现在很多搞后端的同学大部分做的都是后台管理系统,那么管理系统就肯定免不了Excel的导出导入功能,下面这篇文章主要给大家介绍了关于Java简单使用EasyExcel操作读写excel的步骤与要点,需要的朋友可以参考下
    2022-09-09
  • 基于SpringBoot和Vue3的博客平台的用户注册与登录功能实现

    基于SpringBoot和Vue3的博客平台的用户注册与登录功能实现

    本教程将指导您如何使用Spring Boot和Vue3实现用户注册与登录功能。我们将使用Spring Boot作为后端框架,Vue3作为前端框架,同时使用MySQL作为数据库,感兴趣的朋友可以参考一下
    2023-04-04
  • 关于SpringGateway调用服务 接受不到参数问题

    关于SpringGateway调用服务 接受不到参数问题

    这篇文章主要介绍了关于SpringGateway调用服务接受不到参数问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Mybatis 简单启动过程入门详解

    Mybatis 简单启动过程入门详解

    MyBatis是一个持久层框架,简化JDBC操作,SpringBoot集成MyBatis,通过创建项目、准备数据、配置文件、实体类和接口,可以实现数据库操作,使用@Mapper和@Select注解简化接口实现,测试类使用@SpringBootTest和@Test注解启动,本文介绍Mybatis启动过程,感兴趣的朋友一起看看吧
    2025-03-03

最新评论