fix: 启用验证码并生成图片
- captchaEnabled 改为 true - 使用 Java AWT 生成验证码图片(4位随机字符) - 登录时校验验证码并从内存 Map 移除 - 验证码图片为 PNG 格式 Base64 编码
This commit is contained in:
parent
91676531b8
commit
aaf3b0e88f
|
|
@ -3,6 +3,10 @@ package com.pangu.web.controller;
|
|||
import com.pangu.common.core.domain.AjaxResult;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
|
@ -16,13 +20,79 @@ public class LoginController {
|
|||
* 获取验证码
|
||||
*/
|
||||
@GetMapping("/captchaImage")
|
||||
public AjaxResult getCaptchaImage() {
|
||||
public AjaxResult getCaptchaImage() throws Exception {
|
||||
AjaxResult result = AjaxResult.success();
|
||||
// 开发阶段禁用验证码
|
||||
result.put("captchaEnabled", false);
|
||||
result.put("uuid", UUID.randomUUID().toString());
|
||||
|
||||
String uuid = UUID.randomUUID().toString();
|
||||
String code = generateRandomCode(4);
|
||||
|
||||
// 生成验证码图片
|
||||
String base64Img = generateCaptchaImage(code);
|
||||
|
||||
result.put("captchaEnabled", true);
|
||||
result.put("img", base64Img);
|
||||
result.put("uuid", uuid);
|
||||
|
||||
// 存储验证码到内存(实际应存 Redis,这里简化为静态 Map)
|
||||
captchaStore.put(uuid, code.toLowerCase());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// 简易验证码存储(生产环境应使用 Redis)
|
||||
private static final Map<String, String> captchaStore = new HashMap<>();
|
||||
|
||||
/**
|
||||
* 生成随机验证码
|
||||
*/
|
||||
private String generateRandomCode(int length) {
|
||||
String chars = "ABCDEFGHJKLMNPQRSTUVWXYZabcdefghjkmnpqrstuvwxyz23456789";
|
||||
Random random = new Random();
|
||||
StringBuilder code = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
code.append(chars.charAt(random.nextInt(chars.length())));
|
||||
}
|
||||
return code.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成验证码图片
|
||||
*/
|
||||
private String generateCaptchaImage(String code) throws Exception {
|
||||
int width = 100;
|
||||
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, 25));
|
||||
Random random = new Random();
|
||||
Color[] colors = {Color.RED, Color.BLUE, Color.GREEN, Color.ORANGE, Color.MAGENTA};
|
||||
|
||||
for (int i = 0; i < code.length(); i++) {
|
||||
g.setColor(colors[random.nextInt(colors.length)]);
|
||||
g.drawString(String.valueOf(code.charAt(i)), 15 + i * 20, 28);
|
||||
}
|
||||
|
||||
// 干扰线
|
||||
for (int i = 0; i < 3; i++) {
|
||||
g.setColor(colors[random.nextInt(colors.length)]);
|
||||
g.drawLine(random.nextInt(width), random.nextInt(height),
|
||||
random.nextInt(width), random.nextInt(height));
|
||||
}
|
||||
|
||||
g.dispose();
|
||||
|
||||
// 转 Base64
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ImageIO.write(image, "png", baos);
|
||||
return Base64.getEncoder().encodeToString(baos.toByteArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
|
|
@ -31,6 +101,22 @@ public class LoginController {
|
|||
public AjaxResult login(@RequestBody Map<String, String> loginBody) {
|
||||
String username = loginBody.get("username");
|
||||
String password = loginBody.get("password");
|
||||
String code = loginBody.get("code");
|
||||
String uuid = loginBody.get("uuid");
|
||||
|
||||
// 验证码校验
|
||||
if (code == null || uuid == null) {
|
||||
return AjaxResult.error("验证码不能为空");
|
||||
}
|
||||
String storedCode = captchaStore.get(uuid);
|
||||
if (storedCode == null) {
|
||||
return AjaxResult.error("验证码已过期");
|
||||
}
|
||||
if (!storedCode.equals(code.toLowerCase())) {
|
||||
return AjaxResult.error("验证码错误");
|
||||
}
|
||||
// 验证后移除
|
||||
captchaStore.remove(uuid);
|
||||
|
||||
// 开发阶段简单校验:admin/admin123
|
||||
if ("admin".equals(username) && "admin123".equals(password)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue