springboot 项目整合easy-captcha验证码功能

效果

1、验证码使用easy-captcha,在pom文件增加依赖
	<!-- google 验证码 -->
		<dependency>
			<groupId>com.github.whvcse</groupId>
			<artifactId>easy-captcha</artifactId>
		</dependency>
2、增加获取kaptcha的ctrl
package com.*.*.system.controller;


import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


/**
 * @Description
 * @auther zxf
 * @date 29/3/2024 上午 8:49
 */
@RestController
@RequestMapping("kaptcha")
public class KaptchaController {
    @GetMapping("/getKaptcha")
    public void defaultKaptcha(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception{
        httpServletResponse.setHeader("Cache-Control","no-store");
        httpServletResponse.setHeader("Pragma","no-cache");
        httpServletResponse.setDateHeader("Expires",0);
        httpServletResponse.setContentType("image/gif");

        //生成验证码对象,三个参数分别是宽、高、位数
        SpecCaptcha captcha = new SpecCaptcha(100, 38, 4);
        //设置验证码的字符类型为数字和字母混合
        captcha.setCharType(Captcha.TYPE_ONLY_NUMBER);
        // 设置内置字体
        captcha.setCharType(Captcha.FONT_1);
        //验证码存入session
        httpServletRequest.getSession().setAttribute("kaptcha",captcha.text().toLowerCase());

        //输出图片流
        captcha.out(httpServletResponse.getOutputStream());
    }

    public String verify(@RequestParam("code") String code, HttpSession session){
        if (!StringUtils.hasLength(code)){
            return "验证码不能为空";
        }
        String kaptchaCode = session.getAttribute("kaptcha")+"";
        if (!StringUtils.hasLength(kaptchaCode)||!code.toLowerCase().equals(kaptchaCode)){
            return "验证码错误";
        }
        return "验证成功";
    }
}
3、前台
<a-form-item>
	<a-input
	size="large"
	style="width: 80%"
	placeholder="请输入验证码"
	v-decorator="['kaptcha',{rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}]" type="text">
	<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/>
	</a-input>
	<img alt="验证码" style="float: right" width="65px" height="40px" :src="kaptcha" @click="changekaptcha"/>
</a-form-item>

data里配置:
kaptcha: window.location.origin+"/kaptcha/getKaptcha",

更改验证码方法
changekaptcha(){
			this.kaptcha =this.kaptcha+'?d='+new Date().getTime();
		}

3.增加filter
package com.*.*.*.*.config;

import com.alibaba.fastjson.JSONObject;
import com.gc.common.base.message.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

/**
 * @Description
 * @auther zxf
 * @date 1/4/2024 下午 3:05
 */
@Slf4j
@Configuration
public class CaptchaFilter implements Filter {
    private static final String CODE_ANT_URL = "auth/login";
    private static final String CAPTCHA_SESSION_KEY = "kaptcha";
    private static final String CAPTCHA_PARAM_NAME = "kaptcha";
    //请求路径匹配
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("init()......");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request =  (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;

        String url = request.getRequestURL().toString();
        //判断请求路径是否是登录路径
        if(!url.contains(CODE_ANT_URL)){
            filterChain.doFilter(request, response);
            return;
        }
        HttpSession session = request.getSession(false);
        if (session != null) {
                //拿到session中存放的 captcha 属性
                String captcha = (String) session.getAttribute(CAPTCHA_SESSION_KEY);
                if (captcha == null) {
                    returnResult(response, "验证码已过期,请重新获取。");
                    return;
            }
                //获取输入的验证码信息
                String inputCaptcha = request.getParameter(CAPTCHA_PARAM_NAME);
                if (inputCaptcha == null || !captcha.equals(inputCaptcha.trim())) {
                    returnResult(response, "验证码错误,请重新输入。");
                    return;
                }
            } else {
            returnResult(response, "无法验证验证码,因为HTTP会话不存在");
            return;
            }
        //判断令牌是否存在,如果不存在则返回错误结果

        filterChain.doFilter(request,response);
    }

    private void returnResult(HttpServletResponse response, String s) throws IOException {
        Result responseResult = Result.failure(s);
        //把Result对象转换为JSON格式字符串
        String json = JSONObject.toJSONString(responseResult);
        response.setContentType("application/json;charset=utf-8");
        //将json字符串返回给页面
        response.getWriter().write(json);
    }

    @Override
    public void destroy() {
        System.out.println("destroy()......");
    }
}

spring security config中设置优先访问filter

  @Override
    protected void configure(HttpSecurity http) throws Exception {
        //增加filter
        http.addFilterBefore(new CaptchaFilter(), UsernamePasswordAuthenticationFilter.class);
        super.configure(http);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AcWing 786. 第k个数——算法基础课题解

AcWing 786. 第k个数 文章目录 题目描述思路CGo 题目描述 给定一个长度为 n的整数数列&#xff0c;以及一个整数 k&#xff0c;请用快速选择算法求出数列从小到大排序后的第 k 个数。 输入格式 第一行包含两个整数 n 和 k。 第二行包含 n 个整数&#xff08;所有整数均在 …

韩顺平 | 零基础快速学Python

环境准备 开发工具&#xff1a;IDLE、Pycharm、Sublime Text、Eric 、文本编辑器&#xff08;记事本/editplus/notepad&#xff09; Python特点&#xff1a;既支持面向过程OOP、也支持面向对象编程&#xff1b;具有解释性&#xff0c;不需要编程二进制代码&#xff0c;可以直…

MySQL 导入库/建表时/出现乱码

问题描述&#xff1a; 新建不久的项目在使用Navicat for MySQL进行查看数据&#xff0c;发现表中注释的部分乱码&#xff0c;但是项目中获取的数据使用不会。 猜测因为是数据库编码和项目中使用的不一样&#xff0c;又因为项目的连接语句定义了需要编码&#xff0c;故项目运行…

特征融合篇 | 结合内容引导注意力 DEA-Net 思想 实现双主干特征融合新方法 | IEEE TIP 2024

本篇改进已集成到 YOLOv8-Magic 框架。 摘要—单幅图像去雾是一个具有挑战性的不适定问题,它从观察到的雾化图像中估计潜在的无雾图像。一些现有的基于深度学习的方法致力于通过增加卷积的深度或宽度来改善模型性能。卷积神经网络(CNN)结构的学习能力仍然未被充分探索。本文…

AI大模型与网球运动结合的应用场景及案例分析

AI大模型与网球运动结合的未来前景是广阔的&#xff0c;它不仅能够提升运动员的训练和比赛表现&#xff0c;还能改善教练的策略制定、增强观众的观赛体验以及优化网球赛事的管理。以下是几个具体的应用场景&#xff1a; 1. 运动员技能和表现分析 AI大模型可以通过分析高速摄像…

8.list容器的使用

文章目录 list容器1.构造函数代码工程运行结果 2.赋值和交换代码工程运行结果 3.大小操作代码工程运行结果 4.插入和删除代码工程运行结果 5.数据存取工程代码运行结果 6.反转和排序代码工程运行结果 list容器 1.构造函数 /*1.默认构造-无参构造*/ /*2.通过区间的方式进行构造…

FPGA实现CLAHE算法(Verilog)

在介绍CLAHE算法之前必须要先提一下直方图均衡化&#xff0c;直方图均衡化算法是一种常见的图像增强算法&#xff0c;可以让像素的亮度分配的更加均匀从而获得一个比较好的观察效果。 左边是原图&#xff0c;右边是经过直方图均衡化后图&#xff0c;可以看到肋骨什么的可以更…

鸿蒙应用开发-ArkUI 计算器

一、效果图 在正式介绍ArkUI计算器应用之前&#xff0c;我们先来一睹其风采。效果图上的计算器界面简洁大方&#xff0c;每个按钮都经过精心设计&#xff0c;颜色搭配恰到好处&#xff0c;使得整体界面既美观又实用。数字、运算符等按钮排列整齐&#xff0c;用户可以一目了然地…

鸽哒言讯独家最新im即时通讯系统双端源码下载 (中越双语)带安卓未封装、苹果未封装、PC端(全开源)+部署教程

独家最新im即时通讯系统双端源码下载 &#xff08;中越双语&#xff09;带安卓未封装、苹果未封装、PC端&#xff08;全开源&#xff09;部署教程鸽哒IM即时通讯系统是一款类似于weixin的即时通讯软件&#xff0c;具有独立开发的特点。与网络其他聊天软件相比&#xff0c;即时聊…

HTMLCSSJS

HTML基本结构 <html><head><title>标题</title></head><body>页面内容</body> </html> html是一棵DOM树, html是根标签, head和body是兄弟标签, body包括内容相关, head包含对内容的编写相关, title 与标题有关.类似html这种…

Word中插入Endnote参考文献时显示乱码

近期在写文章需要插入参考文献&#xff0c;使用Endnote插入时显示乱码&#xff0c;如下图所示&#xff1a; 文章末尾显示{ADDIN EN REFILIST } 解决方法 在网上找了诸多方法尝试也没有解决&#xff0c;最终找到一篇博客介绍了一种方法&#xff1a; word选项—高级&#xff1…

16.springboot项目下使用事务(springboot-016-transaction)

事务是一个完整的功能&#xff0c;也叫作是一个完整的业务 事务只跟什么SQL语句有关&#xff1f;事务只跟DML语句有关系&#xff1a;增删改 DML,DQL,DDL,TCL,DCL 首先添加两个依赖以及MyBatis代码自动生成插件 <!--MySql驱动--><dependency><groupId>mysql…

【C++】探索C++中的类与对象(上)

​​ &#x1f331;博客主页&#xff1a;青竹雾色间. &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 ✨人生如寄&#xff0c;多忧何为 ✨ C是一种强大的编程语言&#xff0c;其面向对象的特性使得代码结构更加清晰、易于维护和扩展。在C中&#xff0c;类与…

Elasticsearch 压测实践总结

背景 搜索、ES运维场景离不开压力测试。 1.宿主机层面变更&#xff1a;参数调优 & 配置调整 & 硬件升级2.集群层面变更&#xff1a;参数调优3.索引层面变更&#xff1a;mapping调整 当然还有使用层面变更&#xff0c;使用API调优&#xff08;不属于该文章的讨论范围…

京东获得JD商品详情 API 接口(jd.item_get)的详细使用说明,包括如何通过该接口获取商品的基本信息,包括名称、品牌、产地、规格参数等

通过调用京东商品详情API接口&#xff0c;开发者可以获取商品的基本信息&#xff0c;如名称、品牌、产地、规格参数等。此外&#xff0c;还可以获取商品价格信息&#xff0c;包括原价、促销价和活动信息等。同时&#xff0c;该接口还支持获取商品的销量、评价、图片、描述等详细…

MySQL8.0.36 GTID主从同步失败排查

报错信息&#xff1a; Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 6f577885-e5d0-11ee-a94a-0242c0a80067:1 at source log 7364ffd6441c-bin.000006, end_lo…

C语言 | Leetcode C语言题解之3题无重复字符的最长子串

题目&#xff1a; 题解&#xff1a; int lengthOfLongestSubstring(char * s) {//类似于hash的思想//滑动窗口维护int left 0;int right 0;int max 0;int i,j;int len strlen(s);int haveSameChar 0;for(i 0; i < len ; i ){if(left < right){ //检测是否出现重…

编译好的C++应用程序拷贝到其它电脑,提示dll未找到依赖项的解决方法。

编译好的C应用程序拷贝到其它电脑上&#xff0c;运行时出现提示dll未找到依赖项。 由于dll依赖于其它dll&#xff0c;在开发用电脑上的环境不能完全与其它电脑相同。 解决办法是找到调用到的dll依赖的所有dll&#xff0c;拷贝到运行目录下。 在开发电脑上&#xff1a; 1、开…

7.stack容器的使用

文章目录 stack容器常用接口代码工程运行结果 stack容器 常用接口 /*1.push - 入栈*/ /*2.top - 查看栈顶元素*/ /*3.pop - 出栈*/代码工程 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<stack>using namespace std;/*1.push - 入栈*/ /*2.top…

Advanced RAG 01:讨论未经优化的 RAG 系统存在的问题与挑战

编者按&#xff1a; 自 2023 年以来&#xff0c;RAG 已成为基于 LLM 的人工智能系统中应用最为广泛的架构之一。由于诸多产品的关键功能严重依赖RAG&#xff0c;优化其性能、提高检索效率和准确性迫在眉睫&#xff0c;成为当前 RAG 相关研究的核心问题。 我们今天为大家带来的这…