安徽动漫公司 网站制作 安徽网新,wordpress底部制作,wordpress做论坛插件,100人公司局域网搭建效果 实现思路
验证码图片的url由后端的一个Controller生成#xff0c;前端请求这个Controller接口的时候根据当前时间生成一个uuid#xff0c;并把这个uuid在前端使用localStorage缓存起来#xff0c;下一次还是从缓存中获取。 Controller生成验证码之后#xff0c;把前…效果 实现思路
验证码图片的url由后端的一个Controller生成前端请求这个Controller接口的时候根据当前时间生成一个uuid并把这个uuid在前端使用localStorage缓存起来下一次还是从缓存中获取。 Controller生成验证码之后把前端传过来的uuid通过redis缓存起来这里分两次缓存
缓存uuid以uuid为key缓存验证码
这样当点击登录按钮将数据提交到后台登录接口时会从redis中获取uuid然后通过这个uuid去获取验证码和前端用户输入的验证码进行比较。
简单验证码
生成随机字符如数字、字母的字符串并将这些字符绘制到一张图片上最后输出这张图片。
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random; public class CaptchaGenerator { private static final int WIDTH 100; private static final int HEIGHT 40; private static final Random RANDOM new Random(); public static void main(String[] args) { // 生成验证码文本 String captchaText generateCaptchaText(6); // 生成验证码图片 File outputFile new File(captcha.png); generateCaptchaImage(captchaText, outputFile); System.out.println(Captcha generated: captchaText); } private static String generateCaptchaText(int length) { StringBuilder sb new StringBuilder(length); for (int i 0; i length; i) { // 随机选择字符类型 int type RANDOM.nextInt(3); if (type 0) { // 数字 sb.append(RANDOM.nextInt(10)); } else if (type 1) { // 小写字母 sb.append((char) (a RANDOM.nextInt(26))); } else { // 大写字母 sb.append((char) (A RANDOM.nextInt(26))); } } return sb.toString(); } private static void generateCaptchaImage(String captchaText, File outputFile) { BufferedImage bufferedImage new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); Graphics2D g2d bufferedImage.createGraphics(); // 设置背景色 g2d.setColor(Color.WHITE); g2d.fillRect(0, 0, WIDTH, HEIGHT); // 设置字体 Font font new Font(Arial, Font.BOLD, 24); g2d.setFont(font); // 绘制验证码文本 g2d.setColor(Color.BLACK); FontMetrics fontMetrics g2d.getFontMetrics(); int x (WIDTH - fontMetrics.stringWidth(captchaText)) / 2; int y ((HEIGHT - fontMetrics.getHeight()) / 2) fontMetrics.getAscent(); g2d.drawString(captchaText, x, y); // 释放资源 g2d.dispose(); // 输出图片 try { ImageIO.write(bufferedImage, png, outputFile); } catch (IOException e) { e.printStackTrace(); } }
}工具包
Hutool是一个多功能的工具包其中有验证码的功能hutool-captchaeasy-captcha专注验证码
Hutool demo
1、添加依赖
dependencygroupIdcn.hutool/groupIdartifactIdhutool-all/artifactIdversion5.7.16/version
/dependency2、写一个控制器
package com.zhangyu.controller;import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.json.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;RestController
public class CaptchaController {GetMapping(/captcha)public Map captcha(HttpServletRequest request, HttpServletResponse response) throws IOException {// 生成验证码图片 LineCaptcha lineCaptcha CaptchaUtil.createLineCaptcha(200, 100, 4, 4);// 获取验证码图片上的文字String captchaText lineCaptcha.getCode();// 将验证码文字放入session键名为 CAPTCHA_KEYrequest.getSession().setAttribute(CAPTCHA_KEY, captchaText);System.out.println(文字是 captchaText);// 输出图片 BufferedImage image lineCaptcha.getImage();// 图片转base64String base ImageToBase64.convertImageToBase64(image);System.out.println(base文字是 base);// 组装数据Map resultMap new HashMap();resultMap.put(code, captchaText);resultMap.put(img, data:image/png;base64, base);return resultMap;}PostMapping(/submit)public String submit(HttpServletRequest request, RequestBody JSONObject jsonObject) {String captcha jsonObject.getStr(captcha);String sessionCaptcha (String) request.getSession().getAttribute(CAPTCHA_KEY);if (captcha.equalsIgnoreCase(sessionCaptcha)) {return 验证码正确;} else {return 验证码错误请重试;}}
}package com.zhangyu.controller;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.util.Base64;
import java.io.IOException;public class ImageToBase64 {public static String convertImageToBase64(BufferedImage image) throws IOException {ByteArrayOutputStream baos new ByteArrayOutputStream();ImageIO.write(image, png, baos); // 可以改为需要的图片格式如jpgbyte[] imageBytes baos.toByteArray();return Base64.getEncoder().encodeToString(imageBytes);}
}3、前端测试
这里我用vue写了一个简单的demo
templatediv classhomeimg :srcimgUrl clickgetCaptchaImg() altcaptcha title点击刷新input typetext namecaptcha placeholder输入验证码 v-modeltextbutton typesubmit clicksubmitCaptcha()提交/button/div
/templatescript
import baseApi from /api/base
export default {name: HomeView,data () {return {imgUrl: ,text: }},methods: {async getCaptchaImg() {const res await baseApi.getCaptchaImg()this.imgUrl res.img},async submitCaptcha() {const params {captcha: this.text,}const res await baseApi.submitCaptcha(params)}},async mounted () {this.getCaptchaImg()}
}
/script
import ajax from /libs/ajaxconst baseApi {getCaptchaImg: () ajax.request({url: /captcha,method: get}),submitCaptcha: (data) ajax.request({url: /submit,method: post,data})
}
export default baseApidevServer: {port: 9001,open: false,// 配置跨域请求头解决开发环境的跨域问题headers: {Access-Control-Allow-Origin: *,},proxy: http://192.168.18.21:9090/
},4、效果
总结
这里只是用Hutool工具包做了一个demoeasy-captcha我就不展示了也差不多。
真实的场景是返回给前端base64图片和一个uuid并不是我这里展示的图片文字然后提交的时候前端把uuid和输入内容传递给后端由于我这里只是demo所以没有牵扯uuid