From 6ebe8da9b42e773f48260c6d1e0b90307bde5303 Mon Sep 17 00:00:00 2001
From: kongzy <kongzy>
Date: 星期一, 27 十一月 2023 09:28:00 +0800
Subject: [PATCH] 增加验证码
---
assess-system/src/main/java/com/gkhy/assess/system/service/CaptchaService.java | 15 +
assess-common/src/main/java/com/gkhy/assess/common/config/KaptchaTextCreator.java | 68 ++++++++
assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java | 2
assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java | 29 +++
assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java | 2
assess-admin/src/main/java/com/gkhy/assess/admin/controller/CaptchaController.java | 33 ++++
assess-common/pom.xml | 4
assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java | 1
pom.xml | 8 +
assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java | 2
assess-common/src/main/java/com/gkhy/assess/common/config/CaptchaConfig.java | 84 ++++++++++
assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java | 2
assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java | 2
assess-system/src/main/java/com/gkhy/assess/system/service/impl/CaptchaServiceImpl.java | 60 +++++++
assess-system/src/main/java/com/gkhy/assess/system/domain/vo/CaptchaVO.java | 14 +
assess-framework/src/main/java/com/gkhy/assess/framework/aop/LogAspect.java | 130 ++++++++++++++++
16 files changed, 453 insertions(+), 3 deletions(-)
diff --git a/assess-admin/src/main/java/com/gkhy/assess/admin/controller/CaptchaController.java b/assess-admin/src/main/java/com/gkhy/assess/admin/controller/CaptchaController.java
new file mode 100644
index 0000000..18b4e2e
--- /dev/null
+++ b/assess-admin/src/main/java/com/gkhy/assess/admin/controller/CaptchaController.java
@@ -0,0 +1,33 @@
+package com.gkhy.assess.admin.controller;
+
+import com.gkhy.assess.common.api.CommonResult;
+import com.gkhy.assess.system.service.CaptchaService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 验证码操作处理
+ *
+ * @author ruoyi
+ */
+@Api(tags = "验证码前端控制器")
+@RestController
+@RequestMapping("/system/captcha")
+public class CaptchaController
+{
+ @Autowired
+ private CaptchaService captchaService;
+ /**
+ * 生成验证码
+ */
+ @ApiOperation(value = "生成验证码")
+ @GetMapping("/captchaImage")
+ public CommonResult captchaImage()
+ {
+ return CommonResult.success(captchaService.captchaImage());
+ }
+}
diff --git a/assess-common/pom.xml b/assess-common/pom.xml
index 1da62fb..78cd94b 100644
--- a/assess-common/pom.xml
+++ b/assess-common/pom.xml
@@ -107,6 +107,10 @@
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
</dependency>
+ <dependency>
+ <groupId>com.github.penggle</groupId>
+ <artifactId>kaptcha</artifactId>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/assess-common/src/main/java/com/gkhy/assess/common/config/CaptchaConfig.java b/assess-common/src/main/java/com/gkhy/assess/common/config/CaptchaConfig.java
new file mode 100644
index 0000000..35d2fe4
--- /dev/null
+++ b/assess-common/src/main/java/com/gkhy/assess/common/config/CaptchaConfig.java
@@ -0,0 +1,84 @@
+package com.gkhy.assess.common.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;
+
+import static com.google.code.kaptcha.Constants.*;
+
+/**
+ * 验证码配置
+ *
+ */
+@Configuration
+public class CaptchaConfig
+{
+ @Bean(name = "captchaProducer")
+ public DefaultKaptcha getKaptchaBean()
+ {
+ DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+ Properties properties = new Properties();
+ // 是否有边框 默认为true 我们可以自己设置yes,no
+ properties.setProperty(KAPTCHA_BORDER, "yes");
+ // 验证码文本字符颜色 默认为Color.BLACK
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
+ // 验证码图片宽度 默认为200
+ properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
+ // 验证码图片高度 默认为50
+ properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
+ // 验证码文本字符大小 默认为40
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
+ // KAPTCHA_SESSION_KEY
+ properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
+ // 验证码文本字符长度 默认为5
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
+ // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
+ // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
+ properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
+ Config config = new Config(properties);
+ defaultKaptcha.setConfig(config);
+ return defaultKaptcha;
+ }
+
+ @Bean(name = "captchaProducerMath")
+ public DefaultKaptcha getKaptchaBeanMath()
+ {
+ DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+ Properties properties = new Properties();
+ // 是否有边框 默认为true 我们可以自己设置yes,no
+ properties.setProperty(KAPTCHA_BORDER, "yes");
+ // 边框颜色 默认为Color.BLACK
+ properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
+ // 验证码文本字符颜色 默认为Color.BLACK
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
+ // 验证码图片宽度 默认为200
+ properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
+ // 验证码图片高度 默认为50
+ properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
+ // 验证码文本字符大小 默认为40
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
+ // KAPTCHA_SESSION_KEY
+ properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
+ // 验证码文本生成器
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.gkhy.assess.common.config.KaptchaTextCreator");
+ // 验证码文本字符间距 默认为2
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
+ // 验证码文本字符长度 默认为5
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
+ // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
+ properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
+ // 验证码噪点颜色 默认为Color.BLACK
+ properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
+ // 干扰实现类
+ properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
+ // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
+ properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
+ Config config = new Config(properties);
+ defaultKaptcha.setConfig(config);
+ return defaultKaptcha;
+ }
+}
diff --git a/assess-common/src/main/java/com/gkhy/assess/common/config/KaptchaTextCreator.java b/assess-common/src/main/java/com/gkhy/assess/common/config/KaptchaTextCreator.java
new file mode 100644
index 0000000..0678e70
--- /dev/null
+++ b/assess-common/src/main/java/com/gkhy/assess/common/config/KaptchaTextCreator.java
@@ -0,0 +1,68 @@
+package com.gkhy.assess.common.config;
+
+import com.google.code.kaptcha.text.impl.DefaultTextCreator;
+
+import java.util.Random;
+
+/**
+ * 验证码文本生成器
+ *
+ */
+public class KaptchaTextCreator extends DefaultTextCreator
+{
+ private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");
+
+ @Override
+ public String getText()
+ {
+ Integer result = 0;
+ Random random = new Random();
+ int x = random.nextInt(10);
+ int y = random.nextInt(10);
+ StringBuilder suChinese = new StringBuilder();
+ int randomoperands = random.nextInt(3);
+ if (randomoperands == 0)
+ {
+ result = x * y;
+ suChinese.append(CNUMBERS[x]);
+ suChinese.append("*");
+ suChinese.append(CNUMBERS[y]);
+ }
+ else if (randomoperands == 1)
+ {
+ if ((x != 0) && y % x == 0)
+ {
+ result = y / x;
+ suChinese.append(CNUMBERS[y]);
+ suChinese.append("/");
+ suChinese.append(CNUMBERS[x]);
+ }
+ else
+ {
+ result = x + y;
+ suChinese.append(CNUMBERS[x]);
+ suChinese.append("+");
+ suChinese.append(CNUMBERS[y]);
+ }
+ }
+ else
+ {
+ if (x >= y)
+ {
+ result = x - y;
+ suChinese.append(CNUMBERS[x]);
+ suChinese.append("-");
+ suChinese.append(CNUMBERS[y]);
+ }
+ else
+ {
+ result = y - x;
+ suChinese.append(CNUMBERS[y]);
+ suChinese.append("-");
+ suChinese.append(CNUMBERS[x]);
+ }
+ }
+ suChinese.append("=?@" + result);
+ return suChinese.toString();
+ }
+}
\ No newline at end of file
diff --git a/assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java b/assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java
index e619920..053462c 100644
--- a/assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java
+++ b/assess-common/src/main/java/com/gkhy/assess/common/constant/CacheConstant.java
@@ -11,6 +11,8 @@
String SYS_CONFIG_KEY = "sys_config:";
+ String CAPTCHA_CODE_KEY = "captcha_codes:";
+
diff --git a/assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java b/assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java
index 6765e9a..2910ef7 100644
--- a/assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java
+++ b/assess-common/src/main/java/com/gkhy/assess/common/domain/vo/LoginBody.java
@@ -19,6 +19,6 @@
private String password;
@ApiModelProperty(value = "验证码",required = false)
private String code;
- @ApiModelProperty(value = "唯一标识",required = false)
+ @ApiModelProperty(value = "验证码唯一标识",required = false)
private String uuid;
}
diff --git a/assess-framework/src/main/java/com/gkhy/assess/framework/aop/LogAspect.java b/assess-framework/src/main/java/com/gkhy/assess/framework/aop/LogAspect.java
new file mode 100644
index 0000000..41fed63
--- /dev/null
+++ b/assess-framework/src/main/java/com/gkhy/assess/framework/aop/LogAspect.java
@@ -0,0 +1,130 @@
+package com.gkhy.assess.framework.aop;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import cn.hutool.extra.servlet.ServletUtil;
+import cn.hutool.json.JSONObject;
+import com.gkhy.assess.system.utils.ShiroUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Signature;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Pointcut;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.stereotype.Component;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+import java.lang.reflect.Method;
+import java.lang.reflect.Parameter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Aspect
+@Component
+@Slf4j
+public class LogAspect {
+ @Pointcut("execution(public * com.gkhy.assess.*.controller..*.*(..))")
+ public void logPointCut(){
+
+ }
+
+ /**
+ * 处理完请求后执行
+ *
+ * @param joinPoint 切点
+ */
+ @Around("logPointCut()")
+ public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
+ long startTime = System.currentTimeMillis();
+ //获取当前请求对象
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = attributes.getRequest();
+ Signature signature = joinPoint.getSignature();
+ MethodSignature methodSignature = (MethodSignature) signature;
+ Method method = methodSignature.getMethod();
+ StringBuffer requestURL = request.getRequestURL();
+ JSONObject webLog = new JSONObject();
+ String urlStr = request.getRequestURL().toString();
+ webLog.put("basePath",StrUtil.removeSuffix(urlStr, URLUtil.url(urlStr).getPath()));
+ webLog.put("ip", ServletUtil.getClientIP(request,null));
+ webLog.put("method",request.getMethod());
+ Object params=getParameter(method, joinPoint.getArgs());
+ webLog.put("parameter",params);
+ webLog.put("uri",request.getRequestURI());
+ webLog.put("url",requestURL.toString());
+ String userId=ShiroUtils.getUserId()!=null?String.valueOf(ShiroUtils.getUserId()):"";
+ webLog.put("userId",userId);
+ log.info(webLog.toString());
+ Object result = joinPoint.proceed();
+ if (result == null) {
+ //如果切到了 没有返回类型的void方法,这里直接返回
+ return null;
+ }
+ long endTime = System.currentTimeMillis();
+ webLog.put("result",result);
+ webLog.put("spendTime",endTime - startTime);
+ log.info(webLog.toString());
+ return result;
+ }
+
+ /**
+ * 拦截异常操作
+ *
+ * @param joinPoint 切点
+ * @param e 异常
+ */
+ @AfterThrowing(value = "logPointCut()", throwing = "e")
+ public void doAfterThrowing(JoinPoint joinPoint, Exception e)
+ {
+ //获取当前请求对象
+ ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+ HttpServletRequest request = attributes.getRequest();
+ String urlStr = request.getRequestURL().toString();
+ log.error("@AfterThrowing异常通知:url={},出错了error_message={}", urlStr,e.getMessage());
+ }
+
+
+
+ /**
+ * 根据方法和传入的参数获取请求参数
+ */
+ private Object getParameter(Method method, Object[] args) {
+ List<Object> argList = new ArrayList<>();
+ Parameter[] parameters = method.getParameters();
+ for (int i = 0; i < parameters.length; i++) {
+ //将RequestBody注解修饰的参数作为请求参数
+ RequestBody requestBody = parameters[i].getAnnotation(RequestBody.class);
+ if (requestBody != null) {
+ argList.add(args[i]);
+ }
+ //将RequestParam注解修饰的参数作为请求参数
+ RequestParam requestParam = parameters[i].getAnnotation(RequestParam.class);
+ if (requestParam != null) {
+ Map<String, Object> map = new HashMap<>();
+ String key = parameters[i].getName();
+ if (StrUtil.isNotEmpty(requestParam.value())) {
+ key = requestParam.value();
+ }
+ map.put(key, args[i]);
+ argList.add(map);
+ }
+ }
+ if (argList.size() == 0) {
+ return null;
+ } else if (argList.size() == 1) {
+ return argList.get(0);
+ } else {
+ return argList;
+ }
+ }
+
+}
diff --git a/assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java b/assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java
index c3aa3c5..ff4fa0a 100644
--- a/assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java
+++ b/assess-framework/src/main/java/com/gkhy/assess/framework/config/DruidConfig.java
@@ -80,6 +80,7 @@
String commonJsPattern=pattern.replaceAll("\\*","js/common.js");
final String filePath="support/http/resources/js/common.js";
Filter filter=new Filter() {
+
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest,servletResponse);
@@ -91,6 +92,7 @@
text=text.replaceAll("powered.*?shrek.wang</a>","");
servletResponse.getWriter().write(text);
}
+
};
diff --git a/assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java b/assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java
index db4a372..03740b0 100644
--- a/assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java
+++ b/assess-framework/src/main/java/com/gkhy/assess/framework/interceptor/LogInterceptor.java
@@ -26,7 +26,7 @@
MDC.put("requestId", requestId);
MDC.put("clientIP", ip);
MDC.put("url", url);
- String userId= String.valueOf(ShiroUtils.getUserId());
+ String userId= ShiroUtils.getUserId()!=null?String.valueOf(ShiroUtils.getUserId()):"";
MDC.put("userId", userId);
return true;
}
diff --git a/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java b/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java
index a594680..1e30371 100644
--- a/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java
+++ b/assess-framework/src/main/java/com/gkhy/assess/framework/shiro/ShiroConfig.java
@@ -75,6 +75,7 @@
chain.addPathDefinition("/system/agency/getAgencyById","anon");
chain.addPathDefinition("/system/user/agencyRegister","anon");
+ chain.addPathDefinition("/system/captcha/captchaImage","anon");
//除了以上的请求外,其它请求都需要登录
chain.addPathDefinition("/**", "jwtFilter,authc"); // 需登录才能访问
diff --git a/assess-system/src/main/java/com/gkhy/assess/system/domain/vo/CaptchaVO.java b/assess-system/src/main/java/com/gkhy/assess/system/domain/vo/CaptchaVO.java
new file mode 100644
index 0000000..c9db5d6
--- /dev/null
+++ b/assess-system/src/main/java/com/gkhy/assess/system/domain/vo/CaptchaVO.java
@@ -0,0 +1,14 @@
+package com.gkhy.assess.system.domain.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel(value = "验证码对象", description = "验证码对象")
+public class CaptchaVO {
+ @ApiModelProperty("唯一标识")
+ private String uuid;
+ @ApiModelProperty("验证码图片内容,base64")
+ private String image;
+}
diff --git a/assess-system/src/main/java/com/gkhy/assess/system/service/CaptchaService.java b/assess-system/src/main/java/com/gkhy/assess/system/service/CaptchaService.java
new file mode 100644
index 0000000..9361b00
--- /dev/null
+++ b/assess-system/src/main/java/com/gkhy/assess/system/service/CaptchaService.java
@@ -0,0 +1,15 @@
+package com.gkhy.assess.system.service;
+
+import com.gkhy.assess.system.domain.vo.CaptchaVO;
+
+import java.awt.image.BufferedImage;
+
+public interface CaptchaService {
+
+ /**
+ * 生成验证码图片
+ * @return
+ */
+ CaptchaVO captchaImage();
+
+}
diff --git a/assess-system/src/main/java/com/gkhy/assess/system/service/impl/CaptchaServiceImpl.java b/assess-system/src/main/java/com/gkhy/assess/system/service/impl/CaptchaServiceImpl.java
new file mode 100644
index 0000000..f128fef
--- /dev/null
+++ b/assess-system/src/main/java/com/gkhy/assess/system/service/impl/CaptchaServiceImpl.java
@@ -0,0 +1,60 @@
+package com.gkhy.assess.system.service.impl;
+
+import cn.hutool.core.codec.Base64;
+import com.gkhy.assess.common.constant.CacheConstant;
+import com.gkhy.assess.common.exception.ApiException;
+import com.gkhy.assess.common.utils.RedisUtils;
+import com.gkhy.assess.system.domain.vo.CaptchaVO;
+import com.gkhy.assess.system.service.CaptchaService;
+import com.google.code.kaptcha.Producer;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.FastByteArrayOutputStream;
+
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.UUID;
+import java.util.concurrent.TimeUnit;
+
+@Slf4j
+@Service
+public class CaptchaServiceImpl implements CaptchaService {
+ @Resource(name = "captchaProducer")
+ private Producer captchaProducer;
+
+ @Resource(name = "captchaProducerMath")
+ private Producer captchaProducerMath;
+ @Autowired
+ private RedisUtils redisUtils;
+
+ @Override
+ public CaptchaVO captchaImage() {
+ String uuid= UUID.randomUUID().toString();
+ String verifyKey= CacheConstant.CAPTCHA_CODE_KEY+uuid;
+ String capText=captchaProducerMath.createText();
+ String capStr=capText.substring(0,capText.lastIndexOf("@"));
+ String code=capText.substring(capText.lastIndexOf("@")+1);
+ BufferedImage image=captchaProducerMath.createImage(capStr);
+ redisUtils.set(verifyKey,code,2, TimeUnit.MINUTES);
+ // 转换流信息写出
+ FastByteArrayOutputStream os = new FastByteArrayOutputStream();
+ try
+ {
+ ImageIO.write(image, "jpg", os);
+ }
+ catch (IOException e)
+ {
+ log.error(e.getMessage());
+ throw new ApiException("生成验证码失败");
+ }
+ CaptchaVO captchaVO=new CaptchaVO();
+ captchaVO.setUuid(uuid);
+ captchaVO.setImage(Base64.encode(os.toByteArray()));
+ return captchaVO;
+ }
+
+
+}
diff --git a/assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java b/assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java
index 9bfc0cd..6ceaac1 100644
--- a/assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java
+++ b/assess-system/src/main/java/com/gkhy/assess/system/service/impl/SysUserServiceImpl.java
@@ -1,6 +1,7 @@
package com.gkhy.assess.system.service.impl;
import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gkhy.assess.common.api.CommonPage;
import com.gkhy.assess.common.constant.CacheConstant;
@@ -57,6 +58,8 @@
@Override
public AccountVO login(LoginBody loginBody) {
+ // 验证码校验
+ validateCaptcha(loginBody.getUsername(), loginBody.getCode(), loginBody.getUuid());
UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(loginBody.getUsername(), loginBody.getPassword(), false);
Subject subject= SecurityUtils.getSubject();
String msg ;
@@ -84,6 +87,32 @@
}
}
+ /**
+ * 校验验证码
+ *
+ * @param username 用户名
+ * @param code 验证码
+ * @param uuid 唯一标识
+ * @return 结果
+ */
+ public void validateCaptcha(String username, String code, String uuid)
+ {
+ if(StrUtil.isBlank(code)||StrUtil.isBlank(uuid)){
+ throw new ApiException("验证码或验证码标识为空");
+ }
+ String verifyKey = CacheConstant.CAPTCHA_CODE_KEY +uuid;
+ String captcha = (String) redisUtils.get(verifyKey);
+ redisUtils.del(verifyKey);
+ if (StrUtil.isBlank(captcha))
+ {
+ throw new ApiException("验证码已失效");
+ }
+ if (!code.equalsIgnoreCase(captcha))
+ {
+ throw new ApiException("验证码不正确");
+ }
+ }
+
@Override
public void logout() {
String jwtToken = request.getHeader(JwtTokenUtil.USER_LOGIN_TOKEN);
diff --git a/assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java b/assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java
index 682c61b..4fcd1bf 100644
--- a/assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java
+++ b/assess-system/src/main/java/com/gkhy/assess/system/utils/ShiroUtils.java
@@ -25,7 +25,7 @@
public static Long getUserId()
{
- return getSysUser().getId().longValue();
+ return getSysUser()!=null?getSysUser().getId().longValue():null;
}
public static SysUser getSysUser()
diff --git a/pom.xml b/pom.xml
index 82664af..ea92af6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -39,6 +39,7 @@
<java-jwt.version>3.11.0</java-jwt.version>
<fastjson.version>1.2.76</fastjson.version>
<caffeine.version>2.9.3</caffeine.version>
+ <kaptcha.version>2.3.2</kaptcha.version>
</properties>
<dependencyManagement>
<dependencies>
@@ -143,6 +144,13 @@
<version>${caffeine.version}</version>
</dependency>
+ <!-- 验证码 -->
+ <dependency>
+ <groupId>com.github.penggle</groupId>
+ <artifactId>kaptcha</artifactId>
+ <version>${kaptcha.version}</version>
+ </dependency>
+
</dependencies>
</dependencyManagement>
--
Gitblit v1.9.2