From 20dec09bf571e79de0d93b3461a2f831f9fe1024 Mon Sep 17 00:00:00 2001 From: haoxr <1490493387@qq.com> Date: Fri, 24 Mar 2023 22:41:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=AA=8C=E8=AF=81?= =?UTF-8?q?=E7=A0=81=E5=92=8C=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=E9=87=8D?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 24 +++++-- .../common/constant/CacheConstants.java | 16 +++++ .../common/constant/ExcelConstants.java | 16 +++++ .../common/constant/SystemConstants.java | 2 + .../system/common/result/ResultCode.java | 6 ++ .../system/controller/AuthController.java | 12 +++- .../system/controller/SysDeptController.java | 2 +- .../system/controller/SysUserController.java | 3 +- .../easycaptcha/config/EasyCaptchaConfig.java | 60 +++++++++++++++++ .../easycaptcha/enums/VerifyCodeTypeEnum.java | 28 ++++++++ .../producer/EasyCaptchaProducer.java | 61 +++++++++++++++++ .../service/EasyCaptchaService.java | 55 ++++++++++++++++ .../security}/config/SecurityConfig.java | 11 +++- .../filter/JwtAuthenticationFilter.java | 24 ++++--- .../security/filter/VerifyCodeFilter.java | 66 +++++++++++++++++++ .../youlai/system/pojo/dto/CaptchaResult.java | 24 +++++++ src/main/resources/application-dev.yml | 6 ++ src/main/resources/mapper/SysUserMapper.xml | 4 +- .../java/com/youlai/system/RedisTests.java | 5 +- 19 files changed, 403 insertions(+), 22 deletions(-) create mode 100644 src/main/java/com/youlai/system/common/constant/CacheConstants.java create mode 100644 src/main/java/com/youlai/system/common/constant/ExcelConstants.java create mode 100644 src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java create mode 100644 src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java create mode 100644 src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java create mode 100644 src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java rename src/main/java/com/youlai/system/{ => framework/security}/config/SecurityConfig.java (88%) create mode 100644 src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java create mode 100644 src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java diff --git a/pom.xml b/pom.xml index 5da18bbc..67fad1be 100644 --- a/pom.xml +++ b/pom.xml @@ -21,11 +21,11 @@ 17 17 - 5.8.12 + 5.8.15 - 8.0.19 + 8.0.28 1.2.4 - 3.5.3 + 3.5.3.1 4.0.0 @@ -37,8 +37,12 @@ 3.2.1 - 8.3.7 + + 8.5.2 4.8.1 + + + 1.6.2 @@ -161,6 +165,18 @@ ${minio.version} + + com.github.whvcse + easy-captcha + ${easy-captcha.version} + + + + org.openjdk.nashorn + nashorn-core + 15.4 + + diff --git a/src/main/java/com/youlai/system/common/constant/CacheConstants.java b/src/main/java/com/youlai/system/common/constant/CacheConstants.java new file mode 100644 index 00000000..17708e09 --- /dev/null +++ b/src/main/java/com/youlai/system/common/constant/CacheConstants.java @@ -0,0 +1,16 @@ +package com.youlai.system.common.constant; + +/** + * Redis 缓存常量 + * + * @author: haoxr + * @date: 2023/03/24 + */ +public interface CacheConstants { + + /** + * 验证码缓存前缀 + */ + String VERIFY_CODE_CACHE_PREFIX = "AUTH:VERIFY_CODE:"; + +} diff --git a/src/main/java/com/youlai/system/common/constant/ExcelConstants.java b/src/main/java/com/youlai/system/common/constant/ExcelConstants.java new file mode 100644 index 00000000..b0fbe9a8 --- /dev/null +++ b/src/main/java/com/youlai/system/common/constant/ExcelConstants.java @@ -0,0 +1,16 @@ +package com.youlai.system.common.constant; + +/** + * Excel 常量 + * + * @author: haoxr + * @date: 2023/03/24 + */ +public interface ExcelConstants { + + /** + * Excel 模板目录 + */ + String EXCEL_TEMPLATE_DIR="excel-templates"; + +} diff --git a/src/main/java/com/youlai/system/common/constant/SystemConstants.java b/src/main/java/com/youlai/system/common/constant/SystemConstants.java index 7cc2fcca..d6e823d2 100644 --- a/src/main/java/com/youlai/system/common/constant/SystemConstants.java +++ b/src/main/java/com/youlai/system/common/constant/SystemConstants.java @@ -23,4 +23,6 @@ public interface SystemConstants { * 超级管理员角色编码 */ String ROOT_ROLE_CODE = "ROOT"; + + } diff --git a/src/main/java/com/youlai/system/common/result/ResultCode.java b/src/main/java/com/youlai/system/common/result/ResultCode.java index a90492ee..1fe230d7 100644 --- a/src/main/java/com/youlai/system/common/result/ResultCode.java +++ b/src/main/java/com/youlai/system/common/result/ResultCode.java @@ -6,6 +6,8 @@ import lombok.NoArgsConstructor; import java.io.Serializable; /** + * 响应码枚举 + * * @author haoxr * @date 2020-06-23 **/ @@ -25,6 +27,10 @@ public enum ResultCode implements IResultCode, Serializable { USERNAME_OR_PASSWORD_ERROR("A0210", "用户名或密码错误"), PASSWORD_ENTER_EXCEED_LIMIT("A0211", "用户输入密码次数超限"), CLIENT_AUTHENTICATION_FAILED("A0212", "客户端认证失败"), + + VERIFY_CODE_TIMEOUT("A0213", "验证码已过期"), + VERIFY_CODE_ERROR("A0214", "验证码错误"), + TOKEN_INVALID("A0230", "token无效或已过期"), TOKEN_ACCESS_FORBIDDEN("A0231", "token已被禁止访问"), diff --git a/src/main/java/com/youlai/system/controller/AuthController.java b/src/main/java/com/youlai/system/controller/AuthController.java index 62e41a2f..15fc016f 100644 --- a/src/main/java/com/youlai/system/controller/AuthController.java +++ b/src/main/java/com/youlai/system/controller/AuthController.java @@ -1,6 +1,8 @@ package com.youlai.system.controller; import com.youlai.system.common.result.Result; +import com.youlai.system.framework.easycaptcha.service.EasyCaptchaService; +import com.youlai.system.pojo.dto.CaptchaResult; import com.youlai.system.pojo.dto.LoginResult; import com.youlai.system.framework.security.JwtTokenManager; import io.swagger.v3.oas.annotations.Parameter; @@ -14,13 +16,14 @@ import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.*; -@Tag(name = "01.认证管理") +@Tag(name = "01.认证中心") @RestController @RequestMapping("/api/v1/auth") @RequiredArgsConstructor public class AuthController { private final AuthenticationManager authenticationManager; private final JwtTokenManager jwtTokenManager; + private final EasyCaptchaService easyCaptchaService; @Operation(summary = "登录") @PostMapping("/login") @@ -50,4 +53,11 @@ public class AuthController { return Result.success("注销成功"); } + @Operation(summary = "获取验证码") + @GetMapping("/captcha") + public Result getCaptcha() { + CaptchaResult captcha = easyCaptchaService.getCaptcha(); + return Result.success(captcha); + } + } diff --git a/src/main/java/com/youlai/system/controller/SysDeptController.java b/src/main/java/com/youlai/system/controller/SysDeptController.java index a48e0d08..0aa31443 100644 --- a/src/main/java/com/youlai/system/controller/SysDeptController.java +++ b/src/main/java/com/youlai/system/controller/SysDeptController.java @@ -45,7 +45,7 @@ public class SysDeptController { return Result.success(list); } - @Operation(summary = "获取部门详情", security = {@SecurityRequirement(name = "Authorization")}) + @Operation(summary = "获取部门表单数据", security = {@SecurityRequirement(name = "Authorization")}) @GetMapping("/{deptId}/form") public Result getDeptForm( @Parameter(description ="部门ID") @PathVariable Long deptId diff --git a/src/main/java/com/youlai/system/controller/SysUserController.java b/src/main/java/com/youlai/system/controller/SysUserController.java index 566a4b6e..812a0e54 100644 --- a/src/main/java/com/youlai/system/controller/SysUserController.java +++ b/src/main/java/com/youlai/system/controller/SysUserController.java @@ -4,6 +4,7 @@ import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import com.youlai.system.common.constant.ExcelConstants; import com.youlai.system.common.result.PageResult; import com.youlai.system.common.result.Result; import com.youlai.system.common.util.ExcelUtils; @@ -136,7 +137,7 @@ public class SysUserController { response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8")); - String fileClassPath = "excel-templates" + File.separator + fileName; + String fileClassPath = ExcelConstants.EXCEL_TEMPLATE_DIR + File.separator + fileName; InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream(fileClassPath); ServletOutputStream outputStream = response.getOutputStream(); diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java b/src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java new file mode 100644 index 00000000..04c237c2 --- /dev/null +++ b/src/main/java/com/youlai/system/framework/easycaptcha/config/EasyCaptchaConfig.java @@ -0,0 +1,60 @@ +package com.youlai.system.framework.easycaptcha.config; + +import com.youlai.system.framework.easycaptcha.enums.VerifyCodeTypeEnum; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; + +import java.awt.*; + +/** + * @author: haoxr + * @date: 2023/03/24 + */ +@ConfigurationProperties(prefix = "easycaptcha") +@Configuration +@Data +public class EasyCaptchaConfig { + + /** + * 验证码类型 + */ + private VerifyCodeTypeEnum verifyCodeType = VerifyCodeTypeEnum.ARITHMETIC; + + + /** + * 验证码缓存过期时间(单位:秒) + */ + private long ttl = 120l; + + /** + * 验证码内容长度 + */ + private int length = 4; + /** + * 验证码宽度 + */ + private int width = 120; + /** + * 验证码高度 + */ + private int height = 36; + + + /** + * 验证码字体 + */ + private String fontName = "Verdana"; + + /** + * 字体风格 + */ + private Integer fontStyle = Font.PLAIN; + + /** + * 字体大小 + */ + private int fontSize = 20; + + +} diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java b/src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java new file mode 100644 index 00000000..e5aa757a --- /dev/null +++ b/src/main/java/com/youlai/system/framework/easycaptcha/enums/VerifyCodeTypeEnum.java @@ -0,0 +1,28 @@ +package com.youlai.system.framework.easycaptcha.enums; + +/** + * EasyCaptcha 验证码类型枚举 + * + * @author: haoxr + * @date: 2023/03/24 + */ +public enum VerifyCodeTypeEnum { + + /** + * 算数 + */ + ARITHMETIC, + /** + * 中文 + */ + CHINESE, + /** + * 中文闪图 + */ + CHINESE_GIF, + /** + * 闪图 + */ + GIF, + SPEC +} diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java b/src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java new file mode 100644 index 00000000..5972f844 --- /dev/null +++ b/src/main/java/com/youlai/system/framework/easycaptcha/producer/EasyCaptchaProducer.java @@ -0,0 +1,61 @@ +package com.youlai.system.framework.easycaptcha.producer; + +import com.wf.captcha.*; +import com.wf.captcha.base.Captcha; +import com.youlai.system.framework.easycaptcha.config.EasyCaptchaConfig; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Component; + +import java.awt.*; + +/** + * 验证码生成器 + * + * @author: haoxr + * @date: 2023/03/24 + */ + +@Component +@RequiredArgsConstructor +public class EasyCaptchaProducer { + private final EasyCaptchaConfig easyCaptchaConfig; + + public Captcha getCaptcha() { + Captcha captcha; + int width = easyCaptchaConfig.getWidth(); + int height = easyCaptchaConfig.getHeight(); + int length = easyCaptchaConfig.getLength(); + String fontName = easyCaptchaConfig.getFontName(); + + switch (easyCaptchaConfig.getVerifyCodeType()) { + case ARITHMETIC: + captcha = new ArithmeticCaptcha(width, height); + //固定设置为两位,图片为算数运算表达式 + captcha.setLen(2); + break; + case CHINESE: + captcha = new ChineseCaptcha(width, height); + captcha.setLen(length); + break; + case CHINESE_GIF: + captcha = new ChineseGifCaptcha(width, height); + captcha.setLen(length); + break; + case GIF: + captcha = new GifCaptcha(width, height);//最后一位是位数 + captcha.setLen(length); + break; + case SPEC: + captcha = new SpecCaptcha(width, height); + captcha.setLen(length); + break; + default: + throw new RuntimeException("验证码配置信息错误!正确配置查看 VerifyCodeTypeEnum "); + } + captcha.setFont(new Font(fontName, easyCaptchaConfig.getFontStyle(), easyCaptchaConfig.getFontSize())); + return captcha; + + } + + +} diff --git a/src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java b/src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java new file mode 100644 index 00000000..79c6b2ff --- /dev/null +++ b/src/main/java/com/youlai/system/framework/easycaptcha/service/EasyCaptchaService.java @@ -0,0 +1,55 @@ +package com.youlai.system.framework.easycaptcha.service; + +import cn.hutool.core.util.IdUtil; +import com.wf.captcha.base.Captcha; +import com.youlai.system.common.constant.CacheConstants; +import com.youlai.system.framework.easycaptcha.config.EasyCaptchaConfig; +import com.youlai.system.framework.easycaptcha.producer.EasyCaptchaProducer; +import com.youlai.system.pojo.dto.CaptchaResult; +import lombok.RequiredArgsConstructor; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Service; + +import java.util.concurrent.TimeUnit; + +/** + * EasyCaptcha 业务类 + * + * @author: haoxr + * @date: 2023/03/24 + */ +@Service +@RequiredArgsConstructor +public class EasyCaptchaService { + + private final EasyCaptchaProducer easyCaptchaProducer; + + private final StringRedisTemplate redisTemplate; + + private final EasyCaptchaConfig easyCaptchaConfig; + + /** + * 获取验证码 + * + * @return + */ + public CaptchaResult getCaptcha() { + // 获取验证码 + Captcha captcha = easyCaptchaProducer.getCaptcha(); + String captchaText = captcha.text(); // 验证码文本 + String captchaBase64 = captcha.toBase64(); // 验证码图片Base64字符串 + + // 验证码文本缓存至Redis,用于登录比较 + String verifyCodeKey = IdUtil.fastSimpleUUID(); + redisTemplate.opsForValue().set(CacheConstants.VERIFY_CODE_CACHE_PREFIX + verifyCodeKey, captchaText, + easyCaptchaConfig.getTtl(), TimeUnit.SECONDS); + + CaptchaResult captchaResult = CaptchaResult.builder() + .verifyCodeKey(verifyCodeKey) + .verifyCodeBase64(captchaBase64) + .build(); + return captchaResult; + } + +} diff --git a/src/main/java/com/youlai/system/config/SecurityConfig.java b/src/main/java/com/youlai/system/framework/security/config/SecurityConfig.java similarity index 88% rename from src/main/java/com/youlai/system/config/SecurityConfig.java rename to src/main/java/com/youlai/system/framework/security/config/SecurityConfig.java index 23d41991..de91b1fc 100644 --- a/src/main/java/com/youlai/system/config/SecurityConfig.java +++ b/src/main/java/com/youlai/system/framework/security/config/SecurityConfig.java @@ -1,9 +1,10 @@ -package com.youlai.system.config; +package com.youlai.system.framework.security.config; import com.youlai.system.framework.security.filter.JwtAuthenticationFilter; import com.youlai.system.framework.security.exception.MyAccessDeniedHandler; import com.youlai.system.framework.security.exception.MyAuthenticationEntryPoint; import com.youlai.system.framework.security.JwtTokenManager; +import com.youlai.system.framework.security.filter.VerifyCodeFilter; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -44,6 +45,9 @@ public class SecurityConfig { .authorizeHttpRequests() .anyRequest().authenticated() .and() + .formLogin() + .loginProcessingUrl("/api/v1/auth/login").permitAll() + .and() .exceptionHandling() .authenticationEntryPoint(myAuthenticationEntryPoint) .accessDeniedHandler(myAccessDeniedHandler) @@ -52,6 +56,9 @@ public class SecurityConfig { // disable cache http.headers().cacheControl(); + // 验证码校验过滤器 + http.addFilterAt(new VerifyCodeFilter(),UsernamePasswordAuthenticationFilter.class); + // JWT 校验过滤器 http.addFilterBefore(new JwtAuthenticationFilter(jwtTokenManager), UsernamePasswordAuthenticationFilter.class); return http.build(); @@ -61,7 +68,7 @@ public class SecurityConfig { public WebSecurityCustomizer webSecurityCustomizer() { return (web) -> web.ignoring() .requestMatchers( - "/api/v1/auth/login", + "/api/v1/auth/captcha", "/webjars/**", "/doc.html", "/swagger-resources/**", diff --git a/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java b/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java index 925b845a..9852ecd0 100644 --- a/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java +++ b/src/main/java/com/youlai/system/framework/security/filter/JwtAuthenticationFilter.java @@ -2,27 +2,29 @@ package com.youlai.system.framework.security.filter; import cn.hutool.core.util.StrUtil; import com.youlai.system.common.result.ResultCode; -import com.youlai.system.framework.security.JwtTokenManager; import com.youlai.system.common.util.ResponseUtils; -import org.springframework.http.HttpMethod; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.web.filter.OncePerRequestFilter; - +import com.youlai.system.framework.security.JwtTokenManager; import jakarta.servlet.FilterChain; import jakarta.servlet.ServletException; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.web.filter.OncePerRequestFilter; + import java.io.IOException; /** - * JWT token校验拦截器 + * JWT 校验过滤器 * * @author haoxr * @date 2022/10/1 */ public class JwtAuthenticationFilter extends OncePerRequestFilter { + private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/v1/auth/login", "POST"); + private static final String TOKEN_PREFIX = "Bearer "; private final JwtTokenManager tokenManager; @@ -32,15 +34,17 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { } @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { - if(HttpMethod.OPTIONS.matches(request.getMethod()) ){ + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + if (DEFAULT_ANT_PATH_REQUEST_MATCHER.matches(request)) { + // 非登录接口放行 chain.doFilter(request, response); return; } + String jwt = resolveToken(request); if (StrUtil.isNotBlank(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) { try { - // 验证token + // 验证JWT this.tokenManager.validateToken(jwt); // JWT验证有效获取Authentication存入Security上下文 diff --git a/src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java b/src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java new file mode 100644 index 00000000..e4434f68 --- /dev/null +++ b/src/main/java/com/youlai/system/framework/security/filter/VerifyCodeFilter.java @@ -0,0 +1,66 @@ +package com.youlai.system.framework.security.filter; + +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.StrUtil; +import cn.hutool.extra.spring.SpringUtil; +import com.youlai.system.common.constant.CacheConstants; +import com.youlai.system.common.result.ResultCode; +import com.youlai.system.common.util.ResponseUtils; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.security.web.util.matcher.AntPathRequestMatcher; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +/** + * 验证码校验过滤器 + * + * @author haoxr + * @date 2022/10/1 + */ +public class VerifyCodeFilter extends OncePerRequestFilter { + + /** + * 拦截路径 + */ + private static final AntPathRequestMatcher DEFAULT_ANT_PATH_REQUEST_MATCHER = new AntPathRequestMatcher("/api/v1/auth/login", "POST"); + public static final String VERIFY_CODE = "verifyCode"; + public static final String VERIFY_CODE_KEY = "verifyCodeKey"; + + RedisTemplate redisTemplate; + + public VerifyCodeFilter() { + this.redisTemplate = SpringUtil.getBean(StringRedisTemplate.class); + } + + @Override + public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { + if (!DEFAULT_ANT_PATH_REQUEST_MATCHER.matches(request)) { + // 非登录接口放行 + chain.doFilter(request, response); + } else { + // 请求中的验证码 + String requestVerifyCode = request.getParameter(VERIFY_CODE); + + // 缓存中的验证码 + String verifyCodeKey = request.getParameter(VERIFY_CODE_KEY); + Object cacheVerifyCode = redisTemplate.opsForValue().get(CacheConstants.VERIFY_CODE_CACHE_PREFIX + verifyCodeKey); + if (cacheVerifyCode == null) { + ResponseUtils.writeErrMsg(response, ResultCode.VERIFY_CODE_TIMEOUT); + } else { + // 验证码比对 + if (StrUtil.equals(requestVerifyCode, Convert.toStr(cacheVerifyCode))) { + chain.doFilter(request, response); + } else { + ResponseUtils.writeErrMsg(response, ResultCode.VERIFY_CODE_ERROR); + } + } + } + } + +} diff --git a/src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java b/src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java new file mode 100644 index 00000000..f5c471d3 --- /dev/null +++ b/src/main/java/com/youlai/system/pojo/dto/CaptchaResult.java @@ -0,0 +1,24 @@ +package com.youlai.system.pojo.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Data; + +/** + * 验证码响应对象 + * + * @author: haoxr + * @date: 2023/03/24 + */ +@Schema(description ="验证码响应对象") +@Builder +@Data +public class CaptchaResult { + + @Schema(description = "验证码缓存key") + private String verifyCodeKey; + + @Schema(description = "验证码图片Base64字符串") + private String verifyCodeBase64; + +} diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml index 3b542f82..31f4c37f 100644 --- a/src/main/resources/application-dev.yml +++ b/src/main/resources/application-dev.yml @@ -36,6 +36,7 @@ mybatis-plus: # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl + # 认证配置 auth: token: @@ -62,3 +63,8 @@ springdoc: api-docs: enabled: true +# 验证码配置 +easycaptcha: + verifyCodeType: arithmetic + enable: true + ttl: 120 \ No newline at end of file diff --git a/src/main/resources/mapper/SysUserMapper.xml b/src/main/resources/mapper/SysUserMapper.xml index 2f8d41fe..425a0b0e 100644 --- a/src/main/resources/mapper/SysUserMapper.xml +++ b/src/main/resources/mapper/SysUserMapper.xml @@ -20,8 +20,8 @@ FROM sys_user u LEFT JOIN sys_dept d ON u.dept_id = d.id - LEFT JOIN sys_user_role sur ON u.id = sur.user_id - LEFT JOIN sys_role r ON sur.role_id = r.id + LEFT JOIN sys_user_role ur ON u.id = ur.user_id + LEFT JOIN sys_role r ON ur.role_id = r.id u.deleted = 0 AND u.username != 'root' diff --git a/src/test/java/com/youlai/system/RedisTests.java b/src/test/java/com/youlai/system/RedisTests.java index 1b6bde42..b9cefd2b 100644 --- a/src/test/java/com/youlai/system/RedisTests.java +++ b/src/test/java/com/youlai/system/RedisTests.java @@ -1,5 +1,7 @@ package com.youlai.system; +import cn.hutool.core.convert.Convert; +import cn.hutool.core.util.NumberUtil; import com.youlai.system.pojo.entity.SysUser; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.Test; @@ -7,6 +9,8 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; +import java.math.BigDecimal; + /** * Redis 单元测试 * @@ -25,7 +29,6 @@ public class RedisTests { */ @Test public void testRedisSerializer() { - SysUser user = new SysUser(); user.setId(1l); user.setNickname("张三");