SpringBoot后端验证码-防止密码爆破功能

news2024/11/15 7:07:31

一、简介

为了防止网站的用户被通过密码典爆破。引入验证码的功能是十分有必要的。而前端的验证码又仅仅是只防君子不防小人。通过burpsuit等工具很容易就会被绕过。所以后端实现的验证码才是对用户信息安全的一大重要保障。

实现思路:

1.引入图形生成的依赖

2.生成随机4字符,并制作成图片

3.对图片进行Base64形式数据进行传输

4.前端显示


二、引入依赖

<!--        验证码模块-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.12.0</version>
</dependency>

三、验证码生成工具类

public class CaptchaUtil {

    private static final int WIDTH = 200;
    private static final int HEIGHT = 75;
    private static final int FONT_SIZE = 36;
    private static final String DEFAULT_FONT = "Arial";

    /**
     * 生成验证码图像.
     *
     * @param captchaText 验证码原始文本
     * @return Base64编码的图像字符串
     */
    public static String generateCaptchaImage(String captchaText) {
        if (captchaText == null || captchaText.isEmpty()) {
            throw new IllegalArgumentException("Captcha text cannot be null or empty.");
        }

        // 创建图像和图形上下文
        BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) image.getGraphics();

        // 设置背景颜色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        // 绘制验证码文本
        g.setFont(new Font(DEFAULT_FONT, Font.BOLD, FONT_SIZE));
        g.setColor(getRandomColor());
        g.drawString(captchaText, 45, 50);

        // 添加随机线条作为干扰
        addNoiseLines(g);

        // 关闭图形上下文
        g.dispose();

        // 将图像转换为Base64编码的字符串
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageIO.write(image, "png", baos);
            return Base64.getEncoder().encodeToString(baos.toByteArray());
        } catch (Exception e) {
            throw new RuntimeException("Error generating captcha image", e);
        }
    }

    private static void addNoiseLines(Graphics2D g) {
        for (int i = 0; i < 5; i++) {
            g.setColor(getRandomColor());
            g.drawLine(
                    getRandomNumber(WIDTH),
                    getRandomNumber(HEIGHT),
                    getRandomNumber(WIDTH),
                    getRandomNumber(HEIGHT)
            );
        }
    }

    private static Color getRandomColor() {
        return new Color((int) (Math.random() * 255),
                         (int) (Math.random() * 255),
                         (int) (Math.random() * 255));
    }

    private static int getRandomNumber(int bound) {
        return (int) (Math.random() * bound);
    }
}

四、通过Http Session存放验证码与验证

获取(a-z A-Z 0-9)随机四位的验证码功能:

  // 登陆时候获取验证码
    @ApiOperation("获取验证码功能")
    @GetMapping("/GetCaptcha")
    public String GetCaptcha(HttpSession session) {

//        随机生成四位验证码原始数据
        String allowedChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        String randomString = generateRandomString(allowedChars, 4);
        System.out.println("captchaCode " + randomString);

        // 将验证码保存到session中
        session.setAttribute("captcha", randomString); // 使用方法参数session
        String ImageByBase64 = CaptchaUtil.generateCaptchaImage(randomString);
        return ImageByBase64;
    }

用户登陆时候校验验证码功能:

// 实现登陆功能
    @ApiOperation("用户登陆功能")
    @PostMapping("/login")
    public Result Login(@RequestBody LoginDTO loginDTO, HttpSession session) { // 使用同一个HttpSession参数

        String captcha = (String) session.getAttribute("captcha");

        log.info("用户调用login方法");
        if (loginDTO.getCaptcha() == null || !loginDTO.getCaptcha().equalsIgnoreCase(captcha)) {
            session.removeAttribute("captcha");
            return Result.error("验证码出错了噢!");
        }

        // 对密码进行md5加密
        String encryptToMD5 = MD5Util.encryptToMD5(loginDTO.getPassword());

        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(User::getAccount, loginDTO.getAccount())
                .eq(User::getPassword, encryptToMD5);

        User user = userService.getOne(lambdaQueryWrapper);
        if (user == null) {
            return Result.error("很抱歉,查不到此用户");
        }
        user.setPassword("xxxxx");
        return Result.success(user);
    }

五、前端显示Base64格式的图片

前端实现注册的表单

<el-tab-pane label="登陆" name="first">
                <el-form :model="loginForm" ref="loginFormRef" label-width="80px">
                  <el-form-item label="用户名:">
                    <el-input v-model="loginForm.account"></el-input>
                  </el-form-item>
                  <el-form-item label="密码:">
                    <el-input v-model="loginForm.password" show-password></el-input>
                  </el-form-item>
                  <el-form-item label="验证码">
                    <el-input v-model="loginForm.captcha" style="width: 20%;"></el-input>
                    <img :src="captchaImageUrl" alt="验证码" @click="refreshCaptcha" id="captchaImage">
                  </el-form-item>
                </el-form>
              </el-tab-pane>

 先设置为空

export default {
  data() {
    return {
      captchaImageUrl: '', // 初始化为一个空字符串
    }
  },

在点击登陆按钮后,执行getCaptcha函数并设置captchaImageUrl的回显格式为Base64

  fetchCaptcha() {
      axios.get('/api/user/GetCaptcha')
        .then(response => {

          this.captchaImageUrl = 'data:image/png;base64,' + response.data;
        })
        .catch(error => {
          console.error('获取验证码失败:', error);
        });
    },

最后进行测试:

注意:实现完成验证码功能后,需要注意用户的操作。如果登陆失败,刷新页面,切换页面。都需要重新更新验证码!


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

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

相关文章

一文揭秘:中小企业选择做软文营销推广的优势有哪些?

在当今这个信息泛滥、注意力稀缺的时代&#xff0c;中小企业作为经济活力的重要组成部分&#xff0c;面临着前所未有的机遇与挑战。而相比于硬广告的直接灌输&#xff0c;软文营销推广以其独特的魅力&#xff0c;成为了中小企业提升品牌形象、吸引目标客户的重要手段。今天投媒…

关于腾讯的那些事(1月新闻纪要)

腾讯AI Lab与Robotics X 2023年度回顾 这份文件是腾讯AI Lab与Robotics X 2023年度回顾&#xff0c;主要回顾了腾讯在人工智能和机器人领域的研究进展、技术创新及成果应用。以下是文件的核心内容总结&#xff1a; 生成式AI的崛起与影响&#xff1a; 生成式AI的崛起彻底革新了…

【分布式系统】注册中心Zookeeper

目录 一.Zookkeeper 概述 1.Zookkeeper 定义 2.Zookkeeper 工作机制 3.Zookkeeper 特点 4.Zookkeeper 数据结构 5.Zookkeeper 应用场景 统一命名服务 统一配置管理 统一集群管理 服务器动态上下线 软负载均衡 6.Zookkeeper 选举机制 第一次启动选举机制 非第一次…

paddleocr运行报错?谈谈解决思路。

&#x1f3c6;本文收录于「Bug调优」专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&&…

使用Keil 点亮LED灯 F103ZET6

1.新建项目 不截图了 2.startup_stm32f10x_hd.s Keil\Packs\Keil\STM32F1xx_DFP\2.2.0\Device\Source\ARM 搜索startup_stm32f10x_hd.s 复制到项目路径&#xff0c;双击Source Group 1 3.项目文件夹新建stm32f10x.h&#xff0c; 新建文件main.c #include "stm32f10x…

储能电源性能测试方案:纳米软件电源测试系统自动化测试服务

储能电源是什么&#xff1f;   储能电源主要由电池组、充电控制器、逆变器、车规级电芯、外壳等组成&#xff0c;是一种能够将电能储存起来并在需要时释放的设备&#xff0c;能够提供稳定、可靠的电力供应。因便携、轻便、环保等特点&#xff0c;储能电源在家用电子设备、车载…

30 华三华为STP

一 为什么要用到STP协议 在开启STP协议后 计算机之间互通 关闭生成树协议后 不能实现互通 为啥 逻辑环路 开通了STP 全部互通 PC>ping 192.168.1.3Ping 192.168.1.3: 32 data bytes, Press Ctrl_C to break From 192.168.1.3: bytes32 seq1 ttl128 time47 ms From 192.168.…

昇思25天打卡营-mindspore-ML- Day14-VisionTransformer图像分类

今天学习了Vision Transformer图像分类&#xff0c;这是一种基于Transformer模型的图像分类方法&#xff0c;它不依赖卷积操作&#xff0c;而是通过自注意力机制捕捉图像块之间的空间关系&#xff0c;从而实现图像分类。 基本原理&#xff1a; 图像分块: 将原始图像划分为多个…

十二、数组

1. 一维数组的创建和初始化 数组是一组相同类型元素的集合。 变长数组是不能初始化的。 数组的初始化是指&#xff0c;在创建数组的同时给数组的内容一些合理初始值&#xff08;初始化&#xff09;。 例如上图 char ch3[ ]"abc";里面方的就是 a b c \0 char ch3[ …

Android 性能优化之启动优化

文章目录 Android 性能优化之启动优化启动状态冷启动温启动热启动 耗时检测检测手段TraceView使用方式缺点 Systrace环境配置使用方式TraceView和Systrace比较 AOP统计耗时环境配置使用 优化白屏优化异步加载优化环境配置使用 延迟加载优化AppStartup 源码下载 Android 性能优化…

VMware取消中文支持,替换vSAN解决方案提上日程!

What is vSAN &#xff1f; 是一款软件定义的企业存储解决方案&#xff0c;支持超融合基础架构系统。vSAN与VMware vSphere 完全集成在一起&#xff0c;作为ESXi Hypervisor内的分布式软件层&#xff0c;通过整合、池化ESXi各个主机上的存储资源&#xff0c;为vSphere虚拟化平…

厦门大学-中央空调分户计费预付费管理系统案例

厦门大学-中央空调分户计费预付费管理系统案例 实现中央空调节能与舒适的双重目标随着社会的发展和人们生活水平的提高&#xff0c;空调已成为现代建筑中不可或缺的设备。传统的集中计费方式已无法满足多样化的用户需求和节能减排的市场趋势。中央空调如何公平、公正、合理的收…

必剪APP视频剪辑的字幕制作方法教程!

你是否还在用pr听一句打一句的制作字幕&#xff1f;你是否还在用ps做字幕然后拉到pr里一句一句的对时间轴&#xff1f;快别用那些老方法啦&#xff0c;繁琐又浪费时间&#xff01;今天给大家推荐一个方便速度的制作字幕的方法&#xff0c;赶快来看看吧&#xff01; 第一步&…

【数据结构】单链表:数据结构中的舞者,穿梭于理论与实践的舞池

欢迎来到白刘的领域 Miracle_86.-CSDN博客 系列专栏 数据结构与算法 先赞后看&#xff0c;已成习惯 创作不易&#xff0c;多多支持&#xff01; 一、链表的概念和结构 1.1 链表的概念 在上一篇文章中&#xff0c;我们了解了线性表(linear list)&#xff0c;并且学习了其…

后端学习(一)

添加数据库包&#xff1a; 数据库连接时 发生错误&#xff1a; 解决方式&#xff1a; SqlConnection conn new SqlConnection("serverlocalhost;databaseMyBBSDb;uidsa;pwd123456;Encryptfalse;") ;conn.Open();SqlCommand cmd new SqlCommand("SELECT * FROM…

算法012:将x减到0的最小操作数

将x减到0的最小操作数. - 备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能,轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/ 这个题使用到的是滑动窗口。 乍一看&#xff0c…

JAVA Tesseract OCR引擎

Tess4j是一个基于Tesseract OCR引擎的Java库, Tesseract库最初由惠普实验室于1985年开发&#xff0c;后来被Google收购并于2006年开源。识别效果不好&#xff0c;速度还慢&#xff0c;但是好早好早了。 一、POM依赖 <!--OCR识别https://digi.bib.uni-mannheim.de/tesserac…

MySQL篇四:表的约束

文章目录 前言1. 空属性2. 默认值3. 列描述4. zerofill5. 主键6. 自增长7. 唯一键8. 外键 前言 真正约束字段的是数据类型&#xff0c;但是数据类型约束很单一&#xff0c;需要有一些额外的约束&#xff0c;更好的保证数据的合法性&#xff0c;从业务逻辑角度保证数据的正确性。…

26.6 Django模型层

1. 模型层 1.1 模型层的作用 模型层(Model Layer)是MVC或MTV架构中的一个核心组成部分, 它主要负责定义和管理应用程序中的数据结构及其行为. 具体职责包括: * 1. 封装数据: 模型层封装了应用程序所需的所有数据, 这些数据以结构化的形式存在, 如数据库表, 对象等. * 2. 数据…

20K star!手把手教会你搞定 LLM 微调,超详细收藏我这篇就够了

LLM&#xff08;大语言模型&#xff09;微调一直都是老大难问题&#xff0c;不仅因为微调需要大量的计算资源&#xff0c;而且微调的方法也很多&#xff0c;要去尝试每种方法的效果&#xff0c;需要安装大量的第三方库和依赖&#xff0c;甚至要接入一些框架&#xff0c;可能在还…