SpringBoot 实现图形验证码

news2024/12/25 13:34:26

一、最终结果展示

 

二、前端代码

2.1 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/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

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

   <dependency>
       <groupId>cn.hutool</groupId>
       <artifactId>hutool-captcha</artifactId>
       <version>5.8.22</version>
   </dependency>

3.2 配置yml

captcha:
  width: 100
  height: 40
  session:
    code: CAPTCHA_SESSION_CODE
    date: CAPTCHA_SESSION_DATE

3.3 CaptchaController.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

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 即可。

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

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

相关文章

(leetcode学习)236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个节点 p、q&#xff0c;最近公共祖先表示为一个节点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一个节点也可以是它自己的祖…

Q238. 除自身以外数组的乘积

思路 一开始想到的是按位乘 看了题解&#xff0c;思路是存i左边的乘积和 与 i右边的乘积和 代码一&#xff1a; 需要三次循环,需要额外空间 left和right数组 代码&#xff1a; public int[] productExceptSelf(int[] nums) {int[] left new int[nums.length];int[] right …

python题解

空间三角形 输入在三维空间的三角形三个顶点A&#xff0c;B&#xff0c;C的坐标&#xff08;x,y,z&#xff09;&#xff0c;计算并输出三角形面积。不考虑不能构成三角形的特殊情况。 格式 输入格式&#xff1a; 依次输入三个顶点A&#xff0c;B&#xff0c;C的坐标&#xff…

CISSP,信息安全圈公认的高含金量证书

在数字化和信息化迅速发展的时代&#xff0c;信息安全的重要性愈发突出。 网络攻击、数据泄露和隐私问题频发&#xff0c;使得企业和组织对信息安全专业人士的需求不断增加。 CISSP&#xff08;Certified Information Systems Security Professional&#xff09;作为信息安全领…

文字描边效果

文字描边效果可以通过text-shadow来实现&#xff0c;也可以通过-webkit-text-stroke来实现 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, i…

MySQL数据库练习(5)

1.建库建表 # 使用数据库 use mydb16_trigger;# 表格goods create table goods( gid char(8) primary key, name varchar(10), price decimal(8,2), num int);# 表格orders create table orders( oid int primary key auto_increment, gid char(10) not null, name varchar(10…

MYSQL第五次作业

1、触发器 建立两个表:goods(商品表)、orders(订单表) mysql> use mydb16_trigger; Database changed mysql> create table goods-> (-> gid char(8) primary key,-> name varchar(10),-> price decimal(8,2),-> num int-> ); Query O…

MySQL零散拾遗(四)--- 使用聚合函数时需要注意的点点滴滴

聚合函数 聚合函数作用于一组数据&#xff0c;并对一组数据返回一个值。 常见的聚合函数&#xff1a;SUM()、MAX()、MIN()、AVG()、COUNT() 对COUNT()聚合函数的更深一层理解 COUNT函数的作用&#xff1a;计算指定字段在查询结果中出现的个数&#xff08;不包含NULL值&#…

C++操作Smgp协议的相关教程

SGIP是中国网通为实现短信业务而制定的一种通信协议&#xff0c;用于在短消息网关&#xff08;SMG&#xff09;和服务提供商&#xff08;SP&#xff09;之间、短消息网关&#xff08;SMG&#xff09;和短消息网关&#xff08;SMG&#xff09;之间通信。 Perl的IO::Async模块提…

SAP PP学习笔记31 - 计划运行的步骤2 - Scheduling(日程计算),BOM Explosion(BOM展开)

上一章讲了计划运行的5大步骤中的前两步&#xff0c;计算净需求和计算批量大小。 SAP PP学习笔记30 - 计划运行的步骤1 - Net requirements calculation 计算净需求(主要讲了安全库存要素)&#xff0c;Lot-size calculation 计算批量大小-CSDN博客 本章继续讲计划运行的后面几…

Q380 O(1)时间获取插入删除元素

思路 insert 其实用得到search&#xff0c;remove也是&#xff0c;当时o(1)想到的是hash set&#xff0c;但是对于random取,随机数相当于获得的是index,根据index获取元素 Set 数据结构不符合。 随机获取应该是数组&#xff0c;但是数组搜索和删除不是o(1) 最后的思路是 用h…

怎么防止文件在通讯软件外泄

为了防止文件在通讯软件外泄&#xff0c;企业可以采取一系列综合性的措施来加强管理和防护。 1. 使用高级别软件 企业级聊天软件&#xff1a;使用企业级聊天软件&#xff0c;这类软件通常具备更强大的安全管理功能&#xff0c;如文件传输加密、访问权限控制、审计日志记录等。…

【C++】深度解析:用 C++ 模拟实现 list 类,探索其底层实现细节

目录 list介绍 list模拟实现 list 节点类 list 的迭代器 定义 构造函数 解引用 operator前置和--与后置和-- operator与operator! list 类 构造函数 begin()和end() 拷贝构造 erase() clear() 析构函数 insert push_back 和 push_front pop_back 和 pop_front…

CTF-pwn-虚拟化-vmmware 前置

文章目录 参考vmware逃逸简介虚拟机和主机通信机制(guest to host)共享内存&#xff08;弃用&#xff09;backdoor机制Message_Send和Message_RecvGuestRPC实例RpcOutSendOneRawWork实例 vmware-rpctool info-get guestinfo.ip各个步骤对应的backdoor操作Open RPC channelSend …

数据结构初阶(c语言)-双向链表

这里首先纠正上篇文章一个错误&#xff0c;链表的一个有效数据点应该称为结点而不是节点。 一&#xff0c;双向链表的概念与结构 1.1概念与结构示意图 我们所说的双向链表全称为带头双向循环链表&#xff0c;也就是说此链表带有哨兵位结点(不存放任何数据的结点&#xff0c;且…

Oauth2协议的四种模式

B站视频 概念 Oauth2.0&#xff08;Open Authorization&#xff09; 一个关于授权的开放网络标准 允许用户授权第三方应用访问用户存储在其他服务提供者上的信息 不需要将用户名和密码提供给第三方应用 Oauth2中的各个角色 授权码模式 第一步 获取授权码 以上流程中的授…

产品经理NPDP好考吗?

NPDP是新产品开发专业人员的资格认证&#xff0c;对于希望在产品管理领域取得认可的专业人士来说&#xff0c;NPDP认证是一项重要的资格。 那么&#xff0c;产品经理考取NPDP资格认证究竟难不难呢&#xff1f; 首先&#xff0c;NPDP考试的难易程度取决于考生的背景和准备情况…

通信类IEEE会议——第四届通信技术与信息科技国际学术会议(ICCTIT 2024)

[IEEE 独立出版&#xff0c;中山大学主办&#xff0c;往届均已见刊检索] 第四届通信技术与信息科技国际学术会议&#xff08;ICCTIT 2024&#xff09; 2024 4th International Conference on Communication Technology and Information Technology 重要信息 大会官网&#xf…

C#调用OpenCvSharp实现图像的角点检测

角点检测用于获取图像特征&#xff0c;以支撑运动检测、目标识别、图像匹配等方面的应用。常用的角点检测算法包括Kitchen-Rosenfeld算法、Harris算法、KLT算法、SUSAN算法等&#xff0c;本文学习并测试Harris角点检测算法。   关于Harris算法的数学原理请见参考文献1的第18、…

解开基于大模型的Text2SQL的神秘面纱

你好&#xff0c;我是 shengjk1&#xff0c;多年大厂经验&#xff0c;努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注&#xff01;你会有如下收益&#xff1a; 了解大厂经验拥有和大厂相匹配的技术等 希望看什么&#xff0c;评论或者私信告诉我&#xff01; 文章目录 一…