SpringBoot 实现图形验证码

一、最终结果展示

二、前端代码

2.1 index.html

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

</script>
</body>

</html>

2.2 success.html

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.1 引入依赖

html 复制代码
   <dependency>
       <groupId>cn.hutool</groupId>
       <artifactId>hutool-captcha</artifactId>
       <version>5.8.22</version>
   </dependency>

3.2 配置yml

html 复制代码
captcha:
  width: 100
  height: 40
  session:
    code: CAPTCHA_SESSION_CODE
    date: CAPTCHA_SESSION_DATE

3.3 CaptchaController.java

java 复制代码
package com.example.captchademo.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.ICaptcha;
import com.example.captchademo.model.CaptchaProperties;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 
 * Date: 2024-07-24
 * Time: 21:40
 */

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @Autowired
    private CaptchaProperties captchaProperties;

    private static long VALID_TIME = 60*1000;

    @RequestMapping("/get")
    public void getCaptcha(HttpSession session, HttpServletResponse response){
        ICaptcha captcha = CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
        try {
            captcha.write(response.getOutputStream());
            //禁止缓存
            response.setHeader("Prama", "No-cache");
            //设置返回的格式
            response.setContentType("image/jpeg");
            //打印验证码
            System.out.println(captcha.getCode());
            //存储Session
            session.setAttribute(captchaProperties.getSession().getCode(), captcha.getCode());
            session.setAttribute(captchaProperties.getSession().getDate(), System.currentTimeMillis());
            //Servlet的OutputStream记得自行关闭哦!
            response.getOutputStream().close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @RequestMapping("/check")
    public Boolean check(String captchaCode,HttpSession session){

        System.out.println("接收captchaCode:"+captchaCode);
        //参数校验
        //判断用户输入的验证码是否和session中存储的一致
        //是否在有效期内
        if (!StringUtils.hasLength(captchaCode)){
            return false;
        }
        String sessionCode = (String)session.getAttribute(captchaProperties.getSession().getCode());
        Long sessionDate = (Long)session.getAttribute(captchaProperties.getSession().getDate());
        if (captchaCode.equalsIgnoreCase(sessionCode)
                && sessionDate!=null
                && (System.currentTimeMillis() - sessionDate) < VALID_TIME){
            return true;
        }
        return false;

    }
}

3.4 CaptchaProperties.java

java 复制代码
package com.example.captchademo.model;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 
 * Date: 2024-07-24
 * Time: 22:16
 */


@Configuration
@ConfigurationProperties(prefix = "captcha")
@Data
public class CaptchaProperties {
    private Integer width;
    private Integer height;
    private Session session;

    @Data
    public static class Session {
        private String code;
        private String date;
    }
}

前端代码可放置在"captcha-demo\src\main\resources\static"路径下,然后启动项目,在浏览器输入URL:http://127.0.0.1:8080/index.html 即可。

相关推荐
程序员爱钓鱼1 分钟前
Go语言实战案例-实现简易定时提醒程序
后端·google·go
迦蓝叶1 分钟前
JAiRouter 配置文件重构纪实 ——基于单一职责原则的模块化拆分与内聚性提升
java·网关·ai·重构·openai·prometheus·单一职责原则
ST.J4 分钟前
系统架构思考20241204
java·笔记·系统架构
TDengine (老段)23 分钟前
TDengine 时间函数 TIMETRUNCATE 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据
堕落年代24 分钟前
Spring Boot HTTP状态码详解
spring boot·后端·http
Victor35629 分钟前
Redis(49)Redis哨兵如何实现故障检测和转移?
后端
Victor35632 分钟前
Redis(48)Redis哨兵的优点和缺点是什么?
后端
IT_陈寒1 小时前
Python异步编程的7个致命误区:90%开发者踩过的坑及高效解决方案
前端·人工智能·后端
绝无仅有1 小时前
三方系统callback回调MySQL 报错排查与解决:mysql context cancel
后端·面试·github
绝无仅有1 小时前
项目三方合同提交失败的MySQL 错误排查与解决:`context deadline exceeded`
后端·面试·github