david 2 lat temu
rodzic
commit
0c996ba45d

+ 6 - 1
pom.xml

@@ -43,7 +43,12 @@
 			<groupId>org.apache.commons</groupId>
 			<artifactId>commons-pool2</artifactId>
 		</dependency>
-
+		<!-- 图形验证码 -->
+		<dependency>
+			<groupId>com.github.penggle</groupId>
+			<artifactId>kaptcha</artifactId>
+			<version>2.3.2</version>
+		</dependency>
 		<dependency>
 			<groupId>org.springframework.boot</groupId>
 			<artifactId>spring-boot-starter-test</artifactId>

+ 42 - 0
src/main/java/com/roma/romaapi/config/KaptchaConfig.java

@@ -0,0 +1,42 @@
+package com.roma.romaapi.config;
+
+import com.google.code.kaptcha.impl.DefaultKaptcha;
+import com.google.code.kaptcha.util.Config;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import java.util.Properties;
+//Kaptcha配置
+@Configuration
+public class KaptchaConfig {
+    @Bean
+    public DefaultKaptcha producer() {
+        //Properties类
+        Properties properties = new Properties();
+        // 图片边框
+        properties.setProperty("kaptcha.border", "yes");
+        // 边框颜色
+        properties.setProperty("kaptcha.border.color", "105,179,90");
+        // 字体颜色
+        properties.setProperty("kaptcha.textproducer.font.color", "blue");
+        // 图片宽
+        properties.setProperty("kaptcha.image.width", "110");
+        // 图片高
+        properties.setProperty("kaptcha.image.height", "40");
+        // 字体大小
+        properties.setProperty("kaptcha.textproducer.font.size", "30");
+        // session key
+        properties.setProperty("kaptcha.session.key", "code");
+        // 验证码长度
+        properties.setProperty("kaptcha.textproducer.char.length", "4");
+        // 字体
+        properties.setProperty("kaptcha.textproducer.font.names", "宋体,楷体,微软雅黑");
+        //图片干扰
+        properties.setProperty("kaptcha.noise.impl","com.google.code.kaptcha.impl.DefaultNoise");
+        //Kaptcha 使用上述配置
+        Config config = new Config(properties);
+        //DefaultKaptcha对象使用上述配置, 并返回这个Bean
+        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+        defaultKaptcha.setConfig(config);
+        return defaultKaptcha;
+    }
+}

+ 11 - 2
src/main/java/com/roma/romaapi/controller/ApiController.java

@@ -1,13 +1,22 @@
 package com.roma.romaapi.controller;
 
-import com.roma.romaapi.utils.CustomResponse;
-import org.springframework.web.bind.annotation.PathVariable;
+
+import com.roma.romaapi.service.CaptchaService;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 
+import java.io.IOException;
 import java.util.Map;
 
 @RestController
 public class ApiController {
 
+    @Autowired
+    CaptchaService captchaService;
+    // 获取验证码
+    @RequestMapping("/login/verifyCode")
+    public Map<String, Object> loginVerifyCode() throws IOException {
+        return captchaService.captchaCreator();
+    }
 }

+ 83 - 0
src/main/java/com/roma/romaapi/service/CaptchaService.java

@@ -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;
+    }
+}

+ 17 - 0
src/main/java/com/roma/romaapi/utils/UUIDUtil.java

@@ -0,0 +1,17 @@
+package com.roma.romaapi.utils;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+import java.util.UUID;
+@Component
+public class UUIDUtil {
+    /**
+     * 生成32位的随机UUID
+     * @return 字符形式的小写UUID
+     */
+    @Bean
+    public String getUUID32() {
+        return UUID.randomUUID().toString()
+                .replace("-", "").toLowerCase();
+    }
+}

+ 1 - 1
src/main/resources/application.properties

@@ -1 +1 @@
-#服务
server.port=8081

#数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://172.26.143.101:3306/lowcode?serverTimezone=UTC&tinyInt1isBit=false&transformedBitIsBoolean=false
spring.datasource.username = root
spring.datasource.password = mypass

#redis
spring.redis.database=0
spring.redis.password=
#spring.redis.password=name:password
spring.redis.port=6379
spring.redis.host=172.26.143.101
spring.redis.timeout=5000
spring.redis.lettuce.pool.max-active=3
spring.redis.lettuce.pool.min-idle=2
spring.redis.lettuce.pool.max-idle=3
spring.redis.lettuce.pool.max-wait=-1
#spring.redis.lettuce.shutdown-timeout=100
#spring.cache.redis.cache-null-values=false


+#服务
server.port=8081
server.servlet.session.timeout=600

#数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://172.22.255.174:3306/lowcode?serverTimezone=UTC&tinyInt1isBit=false&transformedBitIsBoolean=false
spring.datasource.username = root
spring.datasource.password = mypass

#redis
spring.redis.database=0
spring.redis.password=
#spring.redis.password=name:password
spring.redis.port=6379
spring.redis.host=172.22.255.174
spring.redis.timeout=5000
spring.redis.lettuce.pool.max-active=3
spring.redis.lettuce.pool.min-idle=2
spring.redis.lettuce.pool.max-idle=3
spring.redis.lettuce.pool.max-wait=-1
#spring.redis.lettuce.shutdown-timeout=100
#spring.cache.redis.cache-null-values=false