diff --git a/eladmin-common/src/main/java/me/zhengjie/redis/RedisConfig.java b/eladmin-common/src/main/java/me/zhengjie/config/RedisConfig.java similarity index 73% rename from eladmin-common/src/main/java/me/zhengjie/redis/RedisConfig.java rename to eladmin-common/src/main/java/me/zhengjie/config/RedisConfig.java index e84e2af3..f8d76c96 100644 --- a/eladmin-common/src/main/java/me/zhengjie/redis/RedisConfig.java +++ b/eladmin-common/src/main/java/me/zhengjie/config/RedisConfig.java @@ -1,8 +1,11 @@ -package me.zhengjie.redis; +package me.zhengjie.config; +import cn.hutool.core.lang.Assert; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.parser.ParserConfig; +import com.alibaba.fastjson.serializer.SerializerFeature; import lombok.extern.slf4j.Slf4j; +import me.zhengjie.utils.StringUtils; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.data.redis.RedisProperties; @@ -19,6 +22,10 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisOperations; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.RedisSerializationContext; +import org.springframework.data.redis.serializer.RedisSerializer; +import org.springframework.data.redis.serializer.SerializationException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; import java.time.Duration; /** @@ -116,3 +123,71 @@ public class RedisConfig extends CachingConfigurerSupport { } } + +/** + * Value 序列化 + * + * @author / + * @param + */ + class FastJsonRedisSerializer implements RedisSerializer { + + private Class clazz; + + FastJsonRedisSerializer(Class clazz) { + super(); + this.clazz = clazz; + } + + @Override + public byte[] serialize(T t) throws SerializationException { + if (t == null) { + return new byte[0]; + } + return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8); + } + + @Override + public T deserialize(byte[] bytes) throws SerializationException { + if (bytes == null || bytes.length <= 0) { + return null; + } + String str = new String(bytes, StandardCharsets.UTF_8); + return JSON.parseObject(str, clazz); + } + +} + +/** + * 重写序列化器 + * + * @author / + */ +class StringRedisSerializer implements RedisSerializer { + + private final Charset charset; + + StringRedisSerializer() { + this(StandardCharsets.UTF_8); + } + + private StringRedisSerializer(Charset charset) { + Assert.notNull(charset, "Charset must not be null!"); + this.charset = charset; + } + + @Override + public String deserialize(byte[] bytes) { + return (bytes == null ? null : new String(bytes, charset)); + } + + @Override + public byte[] serialize(Object object) { + String string = JSON.toJSONString(object); + if (StringUtils.isBlank(string)) { + return null; + } + string = string.replace("\"", ""); + return string.getBytes(charset); + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java b/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java new file mode 100644 index 00000000..de7dde31 --- /dev/null +++ b/eladmin-common/src/main/java/me/zhengjie/config/SwaggerConfig.java @@ -0,0 +1,130 @@ +package me.zhengjie.config; + +import com.fasterxml.classmate.TypeResolver; +import com.google.common.base.Predicates; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.core.Ordered; +import org.springframework.data.domain.Pageable; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.ParameterBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.schema.AlternateTypeRule; +import springfox.documentation.schema.AlternateTypeRuleConvention; +import springfox.documentation.schema.ModelRef; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Parameter; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; +import java.util.ArrayList; +import java.util.List; + +import static com.google.common.collect.Lists.newArrayList; +import static springfox.documentation.schema.AlternateTypeRules.newRule; + +/** + * api页面 /swagger-ui.html + * @author Zheng Jie + * @date 2018-11-23 + */ + +@Configuration +@EnableSwagger2 +public class SwaggerConfig { + + @Value("${jwt.header}") + private String tokenHeader; + + @Value("${swagger.enabled}") + private Boolean enabled; + + @Bean + public Docket createRestApi() { + ParameterBuilder ticketPar = new ParameterBuilder(); + List pars = new ArrayList<>(); + ticketPar.name(tokenHeader).description("token") + .modelRef(new ModelRef("string")) + .parameterType("header") + .defaultValue("Bearer ") + .required(true) + .build(); + pars.add(ticketPar.build()); + return new Docket(DocumentationType.SWAGGER_2) + .enable(enabled) + .apiInfo(apiInfo()) + .select() + .paths(Predicates.not(PathSelectors.regex("/error.*"))) + .build() + .globalOperationParameters(pars); + } + + private ApiInfo apiInfo() { + return new ApiInfoBuilder() + .title("eladmin 接口文档") + .version("2.2") + .build(); + } + +} + +/** + * 将Pageable转换展示在swagger中 + */ +@Configuration +class SwaggerDataConfig { + + @Bean + public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) { + return new AlternateTypeRuleConvention() { + @Override + public int getOrder() { + return Ordered.HIGHEST_PRECEDENCE; + } + + @Override + public List rules() { + return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class))); + } + }; + } + + @ApiModel + static class Page { + @ApiModelProperty("页码 (0..N)") + private Integer page; + + @ApiModelProperty("每页显示的数目") + private Integer size; + + @ApiModelProperty("以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc") + private List sort; + + public Integer getPage() { + return page; + } + + public void setPage(Integer page) { + this.page = page; + } + + public Integer getSize() { + return size; + } + + public void setSize(Integer size) { + this.size = size; + } + + public List getSort() { + return sort; + } + + public void setSort(List sort) { + this.sort = sort; + } + } +} diff --git a/eladmin-common/src/main/java/me/zhengjie/exception/BadRequestException.java b/eladmin-common/src/main/java/me/zhengjie/exception/BadRequestException.java index adef657a..d17b18dd 100644 --- a/eladmin-common/src/main/java/me/zhengjie/exception/BadRequestException.java +++ b/eladmin-common/src/main/java/me/zhengjie/exception/BadRequestException.java @@ -2,7 +2,6 @@ package me.zhengjie.exception; import lombok.Getter; import org.springframework.http.HttpStatus; - import static org.springframework.http.HttpStatus.BAD_REQUEST; /** diff --git a/eladmin-common/src/main/java/me/zhengjie/exception/EntityExistException.java b/eladmin-common/src/main/java/me/zhengjie/exception/EntityExistException.java index f9aaa553..5ade7950 100644 --- a/eladmin-common/src/main/java/me/zhengjie/exception/EntityExistException.java +++ b/eladmin-common/src/main/java/me/zhengjie/exception/EntityExistException.java @@ -1,9 +1,6 @@ package me.zhengjie.exception; import org.springframework.util.StringUtils; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.IntStream; /** * @author Zheng Jie @@ -12,16 +9,11 @@ import java.util.stream.IntStream; public class EntityExistException extends RuntimeException { public EntityExistException(Class clazz, String field, String val) { - super(EntityExistException.generateMessage(clazz.getSimpleName(), toMap(field, val))); + super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val)); } - private static String generateMessage(String entity, Map saveBodyParams) { - return StringUtils.capitalize(entity) + - " 已存在 " + - saveBodyParams; - } - - private static Map toMap(String... entries) { - return new HashMap(){{ put(entries[0], entries[1]); }}; + private static String generateMessage(String entity, String field, String val) { + return StringUtils.capitalize(entity) + + " with " + field + " "+ val + " existed"; } } \ No newline at end of file diff --git a/eladmin-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java b/eladmin-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java index c7e2db6a..295bb280 100644 --- a/eladmin-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java +++ b/eladmin-common/src/main/java/me/zhengjie/exception/EntityNotFoundException.java @@ -2,10 +2,6 @@ package me.zhengjie.exception; import org.springframework.util.StringUtils; -import java.util.HashMap; -import java.util.Map; -import java.util.stream.IntStream; - /** * @author Zheng Jie * @date 2018-11-23 @@ -13,16 +9,11 @@ import java.util.stream.IntStream; public class EntityNotFoundException extends RuntimeException { public EntityNotFoundException(Class clazz, String field, String val) { - super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), toMap(field, val))); + super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val)); } - private static String generateMessage(String entity, Map searchParams) { - return StringUtils.capitalize(entity) + - " 不存在 " + - searchParams; - } - - private static Map toMap(String... entries) { - return new HashMap(){{ put(entries[0], entries[1]); }}; + private static String generateMessage(String entity, String field, String val) { + return StringUtils.capitalize(entity) + + " with " + field + " "+ val + " does not exist"; } } \ No newline at end of file diff --git a/eladmin-common/src/main/java/me/zhengjie/exception/handler/ApiError.java b/eladmin-common/src/main/java/me/zhengjie/exception/handler/ApiError.java index 433104f9..9cabb324 100644 --- a/eladmin-common/src/main/java/me/zhengjie/exception/handler/ApiError.java +++ b/eladmin-common/src/main/java/me/zhengjie/exception/handler/ApiError.java @@ -12,7 +12,7 @@ import java.time.LocalDateTime; @Data class ApiError { - private Integer status; + private Integer status = 400; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") private LocalDateTime timestamp; private String message; @@ -21,10 +21,17 @@ class ApiError { timestamp = LocalDateTime.now(); } - ApiError(Integer status, String message) { - this(); - this.status = status; - this.message = message; + public static ApiError error(String message){ + ApiError apiError = new ApiError(); + apiError.setMessage(message); + return apiError; + } + + public static ApiError error(Integer status, String message){ + ApiError apiError = new ApiError(); + apiError.setStatus(status); + apiError.setMessage(message); + return apiError; } } diff --git a/eladmin-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java b/eladmin-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java index 44467412..3815ea40 100644 --- a/eladmin-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java +++ b/eladmin-common/src/main/java/me/zhengjie/exception/handler/GlobalExceptionHandler.java @@ -11,9 +11,7 @@ import org.springframework.security.access.AccessDeniedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; - import java.util.Objects; - import static org.springframework.http.HttpStatus.*; /** @@ -31,8 +29,7 @@ public class GlobalExceptionHandler { public ResponseEntity handleException(Throwable e){ // 打印堆栈信息 log.error(ThrowableUtil.getStackTrace(e)); - ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage()); - return buildResponseEntity(apiError); + return buildResponseEntity(ApiError.error(e.getMessage())); } /** @@ -42,8 +39,7 @@ public class GlobalExceptionHandler { public ResponseEntity handleAccessDeniedException(AccessDeniedException e){ // 打印堆栈信息 log.error(ThrowableUtil.getStackTrace(e)); - ApiError apiError = new ApiError(FORBIDDEN.value(),e.getMessage()); - return buildResponseEntity(apiError); + return buildResponseEntity(ApiError.error(FORBIDDEN.value(),e.getMessage())); } /** @@ -53,8 +49,7 @@ public class GlobalExceptionHandler { public ResponseEntity badRequestException(BadRequestException e) { // 打印堆栈信息 log.error(ThrowableUtil.getStackTrace(e)); - ApiError apiError = new ApiError(e.getStatus(),e.getMessage()); - return buildResponseEntity(apiError); + return buildResponseEntity(ApiError.error(e.getStatus(),e.getMessage())); } /** @@ -64,8 +59,7 @@ public class GlobalExceptionHandler { public ResponseEntity entityExistException(EntityExistException e) { // 打印堆栈信息 log.error(ThrowableUtil.getStackTrace(e)); - ApiError apiError = new ApiError(BAD_REQUEST.value(),e.getMessage()); - return buildResponseEntity(apiError); + return buildResponseEntity(ApiError.error(e.getMessage())); } /** @@ -75,8 +69,7 @@ public class GlobalExceptionHandler { public ResponseEntity entityNotFoundException(EntityNotFoundException e) { // 打印堆栈信息 log.error(ThrowableUtil.getStackTrace(e)); - ApiError apiError = new ApiError(NOT_FOUND.value(),e.getMessage()); - return buildResponseEntity(apiError); + return buildResponseEntity(ApiError.error(NOT_FOUND.value(),e.getMessage())); } /** @@ -87,8 +80,8 @@ public class GlobalExceptionHandler { // 打印堆栈信息 log.error(ThrowableUtil.getStackTrace(e)); String[] str = Objects.requireNonNull(e.getBindingResult().getAllErrors().get(0).getCodes())[1].split("\\."); - ApiError apiError = new ApiError(BAD_REQUEST.value(), str[1] + ":" + e.getBindingResult().getAllErrors().get(0).getDefaultMessage()); - return buildResponseEntity(apiError); + String message = str[1] + ":" + e.getBindingResult().getAllErrors().get(0).getDefaultMessage(); + return buildResponseEntity(ApiError.error(message)); } /** diff --git a/eladmin-common/src/main/java/me/zhengjie/redis/FastJsonRedisSerializer.java b/eladmin-common/src/main/java/me/zhengjie/redis/FastJsonRedisSerializer.java deleted file mode 100644 index 9465aec3..00000000 --- a/eladmin-common/src/main/java/me/zhengjie/redis/FastJsonRedisSerializer.java +++ /dev/null @@ -1,41 +0,0 @@ -package me.zhengjie.redis; - -import com.alibaba.fastjson.JSON; -import com.alibaba.fastjson.serializer.SerializerFeature; -import org.springframework.data.redis.serializer.RedisSerializer; -import org.springframework.data.redis.serializer.SerializationException; -import java.nio.charset.StandardCharsets; - -/** - * Value 序列化 - * - * @author / - * @param - */ -public class FastJsonRedisSerializer implements RedisSerializer { - - private Class clazz; - - FastJsonRedisSerializer(Class clazz) { - super(); - this.clazz = clazz; - } - - @Override - public byte[] serialize(T t) throws SerializationException { - if (t == null) { - return new byte[0]; - } - return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(StandardCharsets.UTF_8); - } - - @Override - public T deserialize(byte[] bytes) throws SerializationException { - if (bytes == null || bytes.length <= 0) { - return null; - } - String str = new String(bytes, StandardCharsets.UTF_8); - return JSON.parseObject(str, clazz); - } - -} diff --git a/eladmin-common/src/main/java/me/zhengjie/redis/StringRedisSerializer.java b/eladmin-common/src/main/java/me/zhengjie/redis/StringRedisSerializer.java deleted file mode 100644 index 0419d5cb..00000000 --- a/eladmin-common/src/main/java/me/zhengjie/redis/StringRedisSerializer.java +++ /dev/null @@ -1,42 +0,0 @@ -package me.zhengjie.redis; - -import cn.hutool.core.lang.Assert; -import com.alibaba.fastjson.JSON; -import me.zhengjie.utils.StringUtils; -import org.springframework.data.redis.serializer.RedisSerializer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; - -/** - * 重写序列化器 - * - * @author / - */ -public class StringRedisSerializer implements RedisSerializer { - - private final Charset charset; - - StringRedisSerializer() { - this(StandardCharsets.UTF_8); - } - - private StringRedisSerializer(Charset charset) { - Assert.notNull(charset, "Charset must not be null!"); - this.charset = charset; - } - - @Override - public String deserialize(byte[] bytes) { - return (bytes == null ? null : new String(bytes, charset)); - } - - @Override - public byte[] serialize(Object object) { - String string = JSON.toJSONString(object); - if (StringUtils.isBlank(string)) { - return null; - } - string = string.replace("\"", ""); - return string.getBytes(charset); - } -} \ No newline at end of file diff --git a/eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerConfig.java b/eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerConfig.java deleted file mode 100644 index d587731e..00000000 --- a/eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerConfig.java +++ /dev/null @@ -1,62 +0,0 @@ -package me.zhengjie.swagger2; - -import com.google.common.base.Predicates; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import springfox.documentation.builders.ApiInfoBuilder; -import springfox.documentation.builders.ParameterBuilder; -import springfox.documentation.builders.PathSelectors; -import springfox.documentation.schema.ModelRef; -import springfox.documentation.service.ApiInfo; -import springfox.documentation.service.Parameter; -import springfox.documentation.spi.DocumentationType; -import springfox.documentation.spring.web.plugins.Docket; -import springfox.documentation.swagger2.annotations.EnableSwagger2; -import java.util.ArrayList; -import java.util.List; - -/** - * api页面 /swagger-ui.html - * @author Zheng Jie - * @date 2018-11-23 - */ - -@Configuration -@EnableSwagger2 -public class SwaggerConfig { - - @Value("${jwt.header}") - private String tokenHeader; - - @Value("${swagger.enabled}") - private Boolean enabled; - - @Bean - public Docket createRestApi() { - ParameterBuilder ticketPar = new ParameterBuilder(); - List pars = new ArrayList<>(); - ticketPar.name(tokenHeader).description("token") - .modelRef(new ModelRef("string")) - .parameterType("header") - .defaultValue("Bearer ") - .required(true) - .build(); - pars.add(ticketPar.build()); - return new Docket(DocumentationType.SWAGGER_2) - .enable(enabled) - .apiInfo(apiInfo()) - .select() - .paths(Predicates.not(PathSelectors.regex("/error.*"))) - .build() - .globalOperationParameters(pars); - } - - private ApiInfo apiInfo() { - return new ApiInfoBuilder() - .title("eladmin 接口文档") - .version("2.2") - .build(); - } - -} diff --git a/eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerDataConfig.java b/eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerDataConfig.java deleted file mode 100644 index 35f0edf1..00000000 --- a/eladmin-common/src/main/java/me/zhengjie/swagger2/SwaggerDataConfig.java +++ /dev/null @@ -1 +0,0 @@ -package me.zhengjie.swagger2; import com.fasterxml.classmate.TypeResolver; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.data.domain.Pageable; import springfox.documentation.schema.AlternateTypeRule; import springfox.documentation.schema.AlternateTypeRuleConvention; import java.util.List; import static com.google.common.collect.Lists.newArrayList; import static springfox.documentation.schema.AlternateTypeRules.newRule; /** * 将Pageable转换展示在swagger中 */ @Configuration public class SwaggerDataConfig { @Bean public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) { return new AlternateTypeRuleConvention() { @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE; } @Override public List rules() { return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class))); } }; } @ApiModel static class Page { @ApiModelProperty("页码 (0..N)") private Integer page; @ApiModelProperty("每页显示的数目") private Integer size; @ApiModelProperty("以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc") private List sort; public Integer getPage() { return page; } public void setPage(Integer page) { this.page = page; } public Integer getSize() { return size; } public void setSize(Integer size) { this.size = size; } public List getSort() { return sort; } public void setSort(List sort) { this.sort = sort; } } } \ No newline at end of file diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java index 0e5f2575..ff0f3552 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/config/SecurityConfig.java @@ -68,7 +68,6 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity httpSecurity) throws Exception { - String loginPath = "login"; httpSecurity // 禁用 CSRF @@ -90,8 +89,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { "/**/*.js" ).anonymous() - .antMatchers( HttpMethod.POST,"/auth/"+ loginPath).anonymous() - .antMatchers("/auth/vCode").anonymous() + .antMatchers(HttpMethod.POST,"/auth/login").anonymous() + .antMatchers(HttpMethod.GET,"/auth/code").anonymous() // 支付宝回调 .antMatchers("/api/aliPay/return").anonymous() .antMatchers("/api/aliPay/notify").anonymous() diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java index de76fb7a..d27e1fd5 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java @@ -1,7 +1,7 @@ package me.zhengjie.modules.security.rest; -import cn.hutool.core.codec.Base64; import cn.hutool.core.util.IdUtil; +import com.wf.captcha.ArithmeticCaptcha; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; @@ -12,7 +12,6 @@ import me.zhengjie.modules.security.security.AuthenticationInfo; import me.zhengjie.modules.security.security.AuthorizationUser; import me.zhengjie.modules.security.security.ImgResult; import me.zhengjie.modules.security.security.JwtUser; -import me.zhengjie.modules.security.utils.VerifyCodeUtils; import me.zhengjie.utils.EncryptUtils; import me.zhengjie.modules.security.utils.JwtTokenUtil; import me.zhengjie.utils.SecurityUtils; @@ -24,8 +23,6 @@ import org.springframework.security.authentication.AccountExpiredException; import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import java.io.ByteArrayOutputStream; -import java.io.IOException; /** * @author Zheng Jie @@ -93,24 +90,16 @@ public class AuthenticationController { } @ApiOperation("获取验证码") - @GetMapping(value = "/vCode") - public ImgResult getCode() throws IOException { - - //生成随机字串 - String verifyCode = VerifyCodeUtils.generateVerifyCode(4); + @GetMapping(value = "/code") + public ImgResult getCode(){ + // 算术类型 https://gitee.com/whvse/EasyCaptcha + ArithmeticCaptcha captcha = new ArithmeticCaptcha(111, 36); + // 几位数运算,默认是两位 + captcha.setLen(2); + // 获取运算的结果:5 + String result = captcha.text(); String uuid = IdUtil.simpleUUID(); - redisService.saveCode(uuid,verifyCode); - // 生成图片 - int w = 111, h = 36; - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - VerifyCodeUtils.outputImage(w, h, stream, verifyCode); - try { - return new ImgResult(Base64.encode(stream.toByteArray()),uuid); - } catch (Exception e) { - e.printStackTrace(); - return null; - } finally { - stream.close(); - } + redisService.saveCode(uuid,result); + return new ImgResult(captcha.toBase64(),uuid); } } diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/utils/VerifyCodeUtils.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/utils/VerifyCodeUtils.java deleted file mode 100644 index 406b2ded..00000000 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/utils/VerifyCodeUtils.java +++ /dev/null @@ -1,195 +0,0 @@ -package me.zhengjie.modules.security.utils; - -import me.zhengjie.utils.StringUtils; - -import java.awt.Color; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.RenderingHints; -import java.awt.geom.AffineTransform; -import java.awt.image.BufferedImage; -import java.io.IOException; -import java.io.OutputStream; -import java.util.Arrays; -import java.util.Random; -import javax.imageio.ImageIO; - -/** - * @author https://blog.csdn.net/ruixue0117/article/details/22829557 - * @date 2019-6-20 17:28:53 - */ -public class VerifyCodeUtils{ - - //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符 - private static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"; - private static Random random = new Random(); - - - /** - * 使用系统默认字符源生成验证码 - * @param verifySize 验证码长度 - * @return 验证码 - */ - public static String generateVerifyCode(int verifySize){ - return generateVerifyCode(verifySize, VERIFY_CODES); - } - - /** - * 使用指定源生成验证码 - * @param verifySize 验证码长度 - * @param sources 验证码字符源 - * @return 验证码 - */ - private static String generateVerifyCode(int verifySize, String sources){ - if(StringUtils.isBlank(sources)){ - sources = VERIFY_CODES; - } - int codesLen = sources.length(); - Random rand = new Random(System.currentTimeMillis()); - StringBuilder verifyCode = new StringBuilder(verifySize); - for(int i = 0; i < verifySize; i++){ - verifyCode.append(sources.charAt(rand.nextInt(codesLen-1))); - } - return verifyCode.toString(); - } - - /** - * 输出指定验证码图片流 - * @param w / - * @param h / - * @param os / - * @param code / - * @throws IOException / - */ - public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{ - int verifySize = code.length(); - BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); - Random rand = new Random(); - Graphics2D g2 = image.createGraphics(); - g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); - Color[] colors = new Color[5]; - Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, - Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, - Color.PINK, Color.YELLOW }; - float[] fractions = new float[colors.length]; - for(int i = 0; i < colors.length; i++){ - colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; - fractions[i] = rand.nextFloat(); - } - Arrays.sort(fractions); - - g2.setColor(Color.GRAY);// 设置边框色 - g2.fillRect(0, 0, w, h); - - Color c = getRandColor(200, 250); - g2.setColor(c);// 设置背景色 - g2.fillRect(0, 2, w, h-4); - - //绘制干扰线 - Random random = new Random(); - g2.setColor(getRandColor(160, 200));// 设置线条的颜色 - for (int i = 0; i < 20; i++) { - int x = random.nextInt(w - 1); - int y = random.nextInt(h - 1); - int xl = random.nextInt(6) + 1; - int yl = random.nextInt(12) + 1; - g2.drawLine(x, y, x + xl + 40, y + yl + 20); - } - - // 添加噪点 - float yawpRate = 0.05f;// 噪声率 - int area = (int) (yawpRate * w * h); - for (int i = 0; i < area; i++) { - int x = random.nextInt(w); - int y = random.nextInt(h); - int rgb = getRandomIntColor(); - image.setRGB(x, y, rgb); - } - - shear(g2, w, h, c);// 使图片扭曲 - - g2.setColor(getRandColor(100, 160)); - int fontSize = h-4; - Font font = new Font("Algerian", Font.ITALIC, fontSize); - g2.setFont(font); - char[] chars = code.toCharArray(); - for(int i = 0; i < verifySize; i++){ - AffineTransform affine = new AffineTransform(); - affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2); - g2.setTransform(affine); - g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10); - } - - g2.dispose(); - ImageIO.write(image, "jpg", os); - } - - private static Color getRandColor(int fc, int bc) { - if (fc > 255) - fc = 255; - if (bc > 255) - bc = 255; - int r = fc + random.nextInt(bc - fc); - int g = fc + random.nextInt(bc - fc); - int b = fc + random.nextInt(bc - fc); - return new Color(r, g, b); - } - - private static int getRandomIntColor() { - int[] rgb = getRandomRgb(); - int color = 0; - for (int c : rgb) { - color = color << 8; - color = color | c; - } - return color; - } - - private static int[] getRandomRgb() { - int[] rgb = new int[3]; - for (int i = 0; i < 3; i++) { - rgb[i] = random.nextInt(255); - } - return rgb; - } - - private static void shear(Graphics g, int w1, int h1, Color color) { - shearX(g, w1, h1, color); - shearY(g, w1, h1, color); - } - - private static void shearX(Graphics g, int w1, int h1, Color color) { - int period = random.nextInt(2); - int frames = 1; - int phase = random.nextInt(2); - for (int i = 0; i < h1; i++) { - double d = (double) (period >> 1) - * Math.sin((double) i / (double) period - + (6.2831853071795862D * (double) phase) - / (double) frames); - g.copyArea(0, i, w1, 1, (int) d, 0); - g.setColor(color); - g.drawLine((int) d, i, 0, i); - g.drawLine((int) d + w1, i, w1, i); - } - - } - - private static void shearY(Graphics g, int w1, int h1, Color color) { - int period = random.nextInt(40) + 10; // 50; - int frames = 20; - int phase = 7; - for (int i = 0; i < w1; i++) { - double d = (double) (period >> 1) - * Math.sin((double) i / (double) period - + (6.2831853071795862D * (double) phase) - / (double) frames); - g.copyArea(i, 0, 1, h1, 0, (int) d); - g.setColor(color); - g.drawLine(i, (int) d, i, 0); - g.drawLine(i, (int) d + h1, i, h1); - - } - } -} \ No newline at end of file diff --git a/eladmin-system/src/main/resources/config/application.yml b/eladmin-system/src/main/resources/config/application.yml index a98b7945..c45c9529 100644 --- a/eladmin-system/src/main/resources/config/application.yml +++ b/eladmin-system/src/main/resources/config/application.yml @@ -22,7 +22,7 @@ spring: redis: #数据库索引 - database: 1 + database: 0 host: 127.0.0.1 port: 6379 password: diff --git a/pom.xml b/pom.xml index 541cb331..87bd2062 100644 --- a/pom.xml +++ b/pom.xml @@ -195,6 +195,11 @@ javax.inject 1 + + com.github.whvcse + easy-captcha + 1.6.2 +