parent
46dbe3cd1d
commit
46ce1ba39f
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,84 @@
|
|||||||
|
package com.luojia_channel.modules.captcha.controller;
|
||||||
|
|
||||||
|
import com.luojia_channel.common.domain.Result;
|
||||||
|
import com.luojia_channel.modules.captcha.utils.CaptchaUtils;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.servlet.http.Cookie;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.servlet.http.HttpSession;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/user")
|
||||||
|
@Tag(name = "图形验证码", description = "图形验证码相关接口")
|
||||||
|
public class CaptchaController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, String> redisTemplate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成验证码图片
|
||||||
|
* @param request
|
||||||
|
* @param res
|
||||||
|
* @throws IOException
|
||||||
|
*/
|
||||||
|
@GetMapping("/captcha")
|
||||||
|
@Operation(
|
||||||
|
summary = "生成验证码图片"
|
||||||
|
)
|
||||||
|
public void generateCaptcha(HttpServletRequest request,
|
||||||
|
HttpServletResponse res) throws IOException {
|
||||||
|
|
||||||
|
CaptchaUtils captcha = new CaptchaUtils();
|
||||||
|
BufferedImage image = captcha.getImage();
|
||||||
|
String text = captcha.getText();
|
||||||
|
|
||||||
|
String captchaKey = UUID.randomUUID().toString();
|
||||||
|
redisTemplate.opsForValue().set("captcha:" + captchaKey, text, 60, TimeUnit.SECONDS);
|
||||||
|
|
||||||
|
Cookie cookie = new Cookie("captchaKey", captchaKey);
|
||||||
|
cookie.setPath("/");
|
||||||
|
res.addCookie(cookie);
|
||||||
|
|
||||||
|
CaptchaUtils.output(image,res.getOutputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证验证码
|
||||||
|
* @param session
|
||||||
|
* @param params
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@PostMapping("/verify-captcha")
|
||||||
|
public Result verifyCaptcha(@RequestBody Map<String, String> params, @CookieValue(value = "captchaKey", required = false) String captchaKey, HttpSession session) {
|
||||||
|
String captcha = params.get("captcha");
|
||||||
|
|
||||||
|
if (captchaKey == null) {
|
||||||
|
return Result.fail(500, "验证码已失效,请重新获取");
|
||||||
|
}
|
||||||
|
|
||||||
|
String redisKey = "captcha:" + captchaKey;
|
||||||
|
String correctCaptcha = redisTemplate.opsForValue().get(redisKey);
|
||||||
|
if (correctCaptcha == null) {
|
||||||
|
return Result.fail(500, "验证码已过期,请重新获取");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (captcha.equalsIgnoreCase(correctCaptcha)) {
|
||||||
|
redisTemplate.delete(redisKey);
|
||||||
|
return Result.success();
|
||||||
|
} else {
|
||||||
|
return Result.fail(500, "图形验证码错误");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
package com.luojia_channel.modules.captcha.utils;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
public class CaptchaUtils {
|
||||||
|
/**
|
||||||
|
* 生成验证码图片的宽度
|
||||||
|
*/
|
||||||
|
private int width = 180;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成验证码图片的高度
|
||||||
|
*/
|
||||||
|
private int height = 30;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 字符样式
|
||||||
|
*/
|
||||||
|
private String[] fontNames = { "宋体", "楷体", "隶书", "微软雅黑" };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义验证码图片的背景颜色为白色
|
||||||
|
*/
|
||||||
|
private Color bgColor = new Color(255, 255, 255);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成随机
|
||||||
|
*/
|
||||||
|
private Random random = new Random();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定义code字符
|
||||||
|
*/
|
||||||
|
private String codes = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记录随机字符串
|
||||||
|
*/
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个随意颜色
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Color randomColor() {
|
||||||
|
int red = random.nextInt(150);
|
||||||
|
int green = random.nextInt(150);
|
||||||
|
int blue = random.nextInt(150);
|
||||||
|
return new Color(red, green, blue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个随机字体
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Font randomFont() {
|
||||||
|
String name = fontNames[random.nextInt(fontNames.length)];
|
||||||
|
int style = random.nextInt(4);
|
||||||
|
int size = random.nextInt(5) + 24;
|
||||||
|
return new Font(name, style, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个随机字符
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private char randomChar() {
|
||||||
|
return codes.charAt(random.nextInt(codes.length()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个空白的BufferedImage对象
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private BufferedImage createImage() {
|
||||||
|
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
|
||||||
|
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||||
|
//设置验证码图片的背景颜色
|
||||||
|
g2.setColor(bgColor);
|
||||||
|
g2.fillRect(0, 0, width, height);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BufferedImage getImage() {
|
||||||
|
BufferedImage image = createImage();
|
||||||
|
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||||
|
StringBuffer sb = new StringBuffer();
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
String s = randomChar() + "";
|
||||||
|
sb.append(s);
|
||||||
|
g2.setColor(randomColor());
|
||||||
|
g2.setFont(randomFont());
|
||||||
|
float x = i * width * 1.0f / 4;
|
||||||
|
g2.drawString(s, x, height - 8);
|
||||||
|
}
|
||||||
|
this.text = sb.toString();
|
||||||
|
drawLine(image);
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绘制干扰线
|
||||||
|
*
|
||||||
|
* @param image
|
||||||
|
*/
|
||||||
|
private void drawLine(BufferedImage image) {
|
||||||
|
Graphics2D g2 = (Graphics2D) image.getGraphics();
|
||||||
|
int num = 5;
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
int x1 = random.nextInt(width);
|
||||||
|
int y1 = random.nextInt(height);
|
||||||
|
int x2 = random.nextInt(width);
|
||||||
|
int y2 = random.nextInt(height);
|
||||||
|
g2.setColor(randomColor());
|
||||||
|
g2.setStroke(new BasicStroke(1.5f));
|
||||||
|
g2.drawLine(x1, y1, x2, y2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void output(BufferedImage image, OutputStream out) throws IOException {
|
||||||
|
ImageIO.write(image, "PNG", out);
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue