SpringBoot 登录验证码

验证码生成工具类

java 复制代码
package com.example.util;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public class CaptchaGenerator {
    private static final String CHARACTERS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    private static final int CAPTCHA_LENGTH = 4;
    private static final Random random = new Random();

    /**
     * 获取创建验证码
     */
    public static String generateCaptcha() {
        StringBuilder captcha = new StringBuilder(CAPTCHA_LENGTH);

        for (int i = 0; i < CAPTCHA_LENGTH; i++) {
            int index = random.nextInt(CHARACTERS.length());
            captcha.append(CHARACTERS.charAt(index));
        }

        return captcha.toString();
    }

    /**
     * 创建验证码图片
     * @param captcha 验证码文本
     * @return 验证码图片
     */
    public static BufferedImage createCaptchaImage(String captcha) {
        int width = 120;
        int height = 40;

        // 创建图片
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();

        // 设置背景色
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, width, height);

        // 设置字体
        g.setFont(new Font("Arial", Font.BOLD, 20));

        // 绘制验证码
        for (int i = 0; i < captcha.length(); i++) {
            g.setColor(getRandomColor());
            int x = 20 + i * 20;
            int y = 25 + random.nextInt(10);
            g.drawString(String.valueOf(captcha.charAt(i)), x, y);
        }

        // 添加干扰线
        for (int i = 0; i < 5; i++) {
            g.setColor(getRandomColor());
            int x1 = random.nextInt(width);
            int y1 = random.nextInt(height);
            int x2 = random.nextInt(width);
            int y2 = random.nextInt(height);
            g.drawLine(x1, y1, x2, y2);
        }

        g.dispose();
        return image;
    }

    /**
     * 获取随机颜色
     * @return 随机颜色
     */
    private static Color getRandomColor() {
        int r = random.nextInt(256);
        int g = random.nextInt(256);
        int b = random.nextInt(256);
        return new Color(r, g, b);
    }
}

获取验证码

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

import com.example.util.CaptchaGenerator;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;

@RestController
@RequestMapping("/captcha")
public class CaptchaController {
    @GetMapping("/generate")
    public void generateCaptcha(HttpServletRequest request, HttpServletResponse response) {
        // 生成验证码
        String captcha = CaptchaGenerator.generateCaptcha();

        // 获取session并存储验证码
        HttpSession session = request.getSession();
        session.setAttribute("captcha", captcha);

        // 生成验证码图片
        BufferedImage image = CaptchaGenerator.createCaptchaImage(captcha);

        // 设置响应头
        response.setContentType("image/png");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setDateHeader("Expires", 0);

        try {
            // 将图片写入响应流
            ImageIO.write(image, "png", response.getOutputStream());
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

使用

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

import *******;

@RestController
@RequestMapping("/api")
public class LogApi {

    /**
     * 登录
     * @param params
     * username 用户名
     * password 密码
     * @return
     */
    @PostMapping("/login")
    public R login(@RequestBody Map<String,String> params, HttpServletRequest request) throws Exception{
        String username = params.get("username");
        String password = params.get("password");
        String captcha = params.get("captcha"); // 获取用户输入的验证码
        // 获取session中的验证码
        HttpSession  session = request.getSession();
        String sessionCaptcha =  (String) session.getAttribute("captcha");

        // 检查验证码是否存在且匹配(忽略大小写)
        if (sessionCaptcha == null || !sessionCaptcha.equalsIgnoreCase(captcha)) {
            return R.failure("验证码错误");
        }
        // 验证通过后移除验证码,防止重复使用
        session.removeAttribute("captcha");

        if(username.equals("admin") && password.equals("password")){
            String s = JwtTokenUtil.generateToken(username, password);
            return R.ok(s);
        }else {
            return R.failure("用户名或密码错误");
        }
    }
}
相关推荐
小羊没烦恼!6 分钟前
浅谈SQL Server中的事务日志(二)----事务日志在修改数据时的角色
前端·数据库·后端·python·web安全·oracle
RuoyiOffice11 分钟前
Spring AI+Vue3 企业知识库设计:让每个答案有依据,让每份资料守住权限
java·spring boot·vue3·rag·企业知识库·spring ai·ruoyi office
IT_陈寒39 分钟前
一文搞懂Vite的核心概念
前端·人工智能·后端
一个简单的TTS开发者40 分钟前
中文TTS工具有哪些-8款主流方案横向对比
人工智能·后端·python·indextts
倔强的石头1061 小时前
【Linux指南】进程通信系列(二):匿名管道 —— pipe 的本质、fork 继承与四种读写规则
java·linux·运维
调试优选官1 小时前
2026年IoT物联网开发赛道年度榜单深度解析:D-coding物联网系统定制与源码交付能力专项解读
java·物联网·struts·iot·开发经验
木井巳1 小时前
【动态规划】三步问题
java·算法·leetcode·动态规划·推荐算法
小张成长计划..1 小时前
【Linux】25:线程概念和控制
java·linux·jvm
高频因子挖掘机1 小时前
量化回测应该保存不复权数据吗?从数据口径到收益计算的工程实践
后端·github·api
高频因子挖掘机2 小时前
实时行情为什么不应该逐只股票请求?批量查询与标的池管理实践
后端·github·api