|
|
@@ -0,0 +1,83 @@
|
|
|
+package com.roma.romaapi.service;
|
|
|
+
|
|
|
+import com.google.code.kaptcha.impl.DefaultKaptcha;
|
|
|
+import com.roma.romaapi.utils.UUIDUtil;
|
|
|
+import jakarta.annotation.Resource;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.data.redis.core.RedisTemplate;
|
|
|
+import org.springframework.data.redis.core.ValueOperations;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import javax.imageio.ImageIO;
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.Base64;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class CaptchaService {
|
|
|
+ @Autowired
|
|
|
+ private DefaultKaptcha producer;
|
|
|
+ @Autowired
|
|
|
+ private RedisTemplate<String, String> redisTemplate;
|
|
|
+ @Autowired
|
|
|
+ private UUIDUtil uuidUtil;
|
|
|
+ //从SpringBoot的配置文件中取出过期时间
|
|
|
+ @Value("${server.servlet.session.timeout}")
|
|
|
+ private Integer timeout;
|
|
|
+ //UUID为key, 验证码为Value放在Redis中
|
|
|
+ public Map<String, Object> createToken(String captcha) {
|
|
|
+ //生成一个token
|
|
|
+ String key = uuidUtil.getUUID32();
|
|
|
+ //生成验证码对应的token 以token为key 验证码为value存在redis中
|
|
|
+ ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
|
|
|
+ valueOperations.set(key, captcha);
|
|
|
+ //设置验证码过期时间
|
|
|
+ redisTemplate.expire(key, timeout, TimeUnit.MINUTES);
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("token", key);
|
|
|
+ map.put("expire", timeout);
|
|
|
+ return map;
|
|
|
+ }
|
|
|
+ //生成captcha验证码
|
|
|
+ public Map<String, Object> captchaCreator() throws IOException {
|
|
|
+ return this.catchaImgCreator();
|
|
|
+ }
|
|
|
+ //验证输入的验证码是否正确
|
|
|
+ public String versifyCaptcha(String token, String inputCode) {
|
|
|
+ //根据前端传回的token在redis中找对应的value
|
|
|
+ ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
|
|
|
+ if (redisTemplate.hasKey(token)) {
|
|
|
+ //验证通过, 删除对应的key
|
|
|
+ if (valueOperations.get(token).equals(inputCode)) {
|
|
|
+ redisTemplate.delete(token);
|
|
|
+ return "true";
|
|
|
+ } else {
|
|
|
+ return "false";
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return "false";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Map<String, Object> catchaImgCreator() throws IOException {
|
|
|
+ //生成文字验证码
|
|
|
+ String text = producer.createText();
|
|
|
+ //生成文字对应的图片验证码
|
|
|
+ BufferedImage image = producer.createImage(text);
|
|
|
+ //将图片写出
|
|
|
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
|
|
+ ImageIO.write(image, "jpg", outputStream);
|
|
|
+ //对写出的字节数组进行Base64编码 ==> 用于传递8比特字节码
|
|
|
+ //生成token
|
|
|
+ Map<String, Object> token = this.createToken(text);
|
|
|
+ Base64.Encoder encoder = Base64.getEncoder();
|
|
|
+ String base64String = encoder.encodeToString(outputStream.toByteArray());
|
|
|
+ token.put("img", base64String);
|
|
|
+ return token;
|
|
|
+ }
|
|
|
+}
|