From 6b36006685a91e8a7dda93e2978dbdd9ecb9a918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B7=E5=86=B7?= Date: Wed, 29 Jul 2020 11:56:00 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20Introducing=20new=20features.=20cl?= =?UTF-8?q?osed=20#I1P8ZX=20=E9=AA=8C=E8=AF=81=E7=A0=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=B8=BAEasyCaptcha?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/constant/SecurityConstants.java | 8 +- .../gateway/config/KaptchaConfiguration.java | 100 ------------------ .../filter/ValidateCodeGatewayFilter.java | 11 +- .../pig/gateway/handler/ImageCodeHandler.java | 87 +++++++-------- 4 files changed, 47 insertions(+), 159 deletions(-) delete mode 100755 pig-gateway/src/main/java/com/pig4cloud/pig/gateway/config/KaptchaConfiguration.java diff --git a/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java b/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java index 2641d5c9..e3dc973e 100755 --- a/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java +++ b/pig-common/pig-common-core/src/main/java/com/pig4cloud/pig/common/core/constant/SecurityConstants.java @@ -68,8 +68,8 @@ public interface SecurityConstants { * sys_oauth_client_details 表的字段,不包括client_id、client_secret */ String CLIENT_FIELDS = "client_id, CONCAT('{noop}',client_secret) as client_secret, resource_ids, scope, " - + "authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, " - + "refresh_token_validity, additional_information, autoapprove"; + + "authorized_grant_types, web_server_redirect_uri, authorities, access_token_validity, " + + "refresh_token_validity, additional_information, autoapprove"; /** * JdbcClientDetailsService 查询语句 @@ -111,4 +111,8 @@ public interface SecurityConstants { */ String DETAILS_LICENSE = "license"; + /** + * 验证码有效期,默认 60秒 + */ + long CODE_TIME = 60; } diff --git a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/config/KaptchaConfiguration.java b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/config/KaptchaConfiguration.java deleted file mode 100755 index b9d06c7e..00000000 --- a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/config/KaptchaConfiguration.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * - * * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com). - * *

- * * Licensed under the GNU Lesser General Public License 3.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * *

- * * https://www.gnu.org/licenses/lgpl.html - * *

- * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. - * - */ - -package com.pig4cloud.pig.gateway.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; - -/** - * @author lengleng - * @date 2019/2/1 - */ -@Configuration -public class KaptchaConfiguration { - - private static final String KAPTCHA_BORDER = "kaptcha.border"; - - private static final String KAPTCHA_TEXTPRODUCER_FONT_COLOR = "kaptcha.textproducer.font.color"; - - private static final String KAPTCHA_TEXTPRODUCER_CHAR_SPACE = "kaptcha.textproducer.char.space"; - - private static final String KAPTCHA_IMAGE_WIDTH = "kaptcha.image.width"; - - private static final String KAPTCHA_IMAGE_HEIGHT = "kaptcha.image.height"; - - private static final String KAPTCHA_TEXTPRODUCER_CHAR_LENGTH = "kaptcha.textproducer.char.length"; - - private static final Object KAPTCHA_IMAGE_FONT_SIZE = "kaptcha.textproducer.font.size"; - - /** - * 默认生成图形验证码宽度 - */ - private static final String DEFAULT_IMAGE_WIDTH = "100"; - - /** - * 默认生成图像验证码高度 - */ - private static final String DEFAULT_IMAGE_HEIGHT = "40"; - - /** - * 默认生成图形验证码长度 - */ - private static final String DEFAULT_IMAGE_LENGTH = "4"; - - /** - * 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue. - */ - private static final String DEFAULT_COLOR_FONT = "black"; - - /** - * 图片边框 - */ - private static final String DEFAULT_IMAGE_BORDER = "no"; - - /** - * 默认图片间隔 - */ - private static final String DEFAULT_CHAR_SPACE = "5"; - - /** - * 验证码文字大小 - */ - private static final String DEFAULT_IMAGE_FONT_SIZE = "30"; - - @Bean - public DefaultKaptcha producer() { - Properties properties = new Properties(); - properties.put(KAPTCHA_BORDER, DEFAULT_IMAGE_BORDER); - properties.put(KAPTCHA_TEXTPRODUCER_FONT_COLOR, DEFAULT_COLOR_FONT); - properties.put(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, DEFAULT_CHAR_SPACE); - properties.put(KAPTCHA_IMAGE_WIDTH, DEFAULT_IMAGE_WIDTH); - properties.put(KAPTCHA_IMAGE_HEIGHT, DEFAULT_IMAGE_HEIGHT); - properties.put(KAPTCHA_IMAGE_FONT_SIZE, DEFAULT_IMAGE_FONT_SIZE); - properties.put(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, DEFAULT_IMAGE_LENGTH); - Config config = new Config(properties); - DefaultKaptcha defaultKaptcha = new DefaultKaptcha(); - defaultKaptcha.setConfig(config); - return defaultKaptcha; - } - -} diff --git a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/ValidateCodeGatewayFilter.java b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/ValidateCodeGatewayFilter.java index a3d166ce..81b8e892 100644 --- a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/ValidateCodeGatewayFilter.java +++ b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/filter/ValidateCodeGatewayFilter.java @@ -21,7 +21,7 @@ package com.pig4cloud.pig.gateway.filter; import cn.hutool.core.util.StrUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; -import com.pig4cloud.pig.common.core.constant.CommonConstants; +import com.pig4cloud.pig.common.core.constant.CacheConstants; import com.pig4cloud.pig.common.core.constant.SecurityConstants; import com.pig4cloud.pig.common.core.exception.ValidateCodeException; import com.pig4cloud.pig.common.core.util.R; @@ -81,8 +81,7 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory { // 校验验证码 checkCode(request); - } - catch (Exception e) { + } catch (Exception e) { ServerHttpResponse response = exchange.getResponse(); response.setStatusCode(HttpStatus.PRECONDITION_REQUIRED); response.getHeaders().setContentType(MediaType.APPLICATION_JSON); @@ -94,8 +93,7 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory { DataBuffer dataBuffer = response.bufferFactory().wrap(bytes); monoSink.success(dataBuffer); - } - catch (JsonProcessingException jsonProcessingException) { + } catch (JsonProcessingException jsonProcessingException) { log.error("对象输出异常", jsonProcessingException); monoSink.error(jsonProcessingException); } @@ -108,6 +106,7 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory { /** * 检查code + * * @param request */ @SneakyThrows @@ -123,7 +122,7 @@ public class ValidateCodeGatewayFilter extends AbstractGatewayFilterFactory { randomStr = request.getQueryParams().getFirst("mobile"); } - String key = CommonConstants.DEFAULT_CODE_KEY + randomStr; + String key = CacheConstants.DEFAULT_CODE_KEY + randomStr; if (!redisTemplate.hasKey(key)) { throw new ValidateCodeException("验证码不合法"); } diff --git a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/handler/ImageCodeHandler.java b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/handler/ImageCodeHandler.java index da9d8a4e..ecd426b4 100755 --- a/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/handler/ImageCodeHandler.java +++ b/pig-gateway/src/main/java/com/pig4cloud/pig/gateway/handler/ImageCodeHandler.java @@ -1,30 +1,30 @@ /* + * Copyright (c) 2018-2025, lengleng All rights reserved. * - * * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com). - * *

- * * Licensed under the GNU Lesser General Public License 3.0 (the "License"); - * * you may not use this file except in compliance with the License. - * * You may obtain a copy of the License at - * *

- * * https://www.gnu.org/licenses/lgpl.html - * *

- * * Unless required by applicable law or agreed to in writing, software - * * distributed under the License is distributed on an "AS IS" BASIS, - * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * * See the License for the specific language governing permissions and - * * limitations under the License. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * Neither the name of the pig4cloud.com developer nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * Author: lengleng (wangiegie@gmail.com) */ package com.pig4cloud.pig.gateway.handler; -import com.google.code.kaptcha.Producer; -import com.pig4cloud.pig.common.core.constant.CommonConstants; -import lombok.RequiredArgsConstructor; +import com.pig4cloud.pig.common.core.constant.CacheConstants; +import com.pig4cloud.pig.common.core.constant.SecurityConstants; +import com.wf.captcha.ArithmeticCaptcha; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.core.io.buffer.DefaultDataBuffer; -import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.core.io.ByteArrayResource; import org.springframework.data.redis.core.RedisTemplate; +import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.stereotype.Component; @@ -35,55 +35,40 @@ import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Mono; -import javax.imageio.ImageIO; -import java.awt.image.BufferedImage; -import java.io.IOException; import java.util.concurrent.TimeUnit; /** * @author lengleng - * @date 2019/2/1 验证码生成逻辑处理类 + * @date 2018/7/5 + * 验证码生成逻辑处理类 */ @Slf4j @Component -@RequiredArgsConstructor +@AllArgsConstructor public class ImageCodeHandler implements HandlerFunction { - - private final Producer producer; - + private static final Integer DEFAULT_IMAGE_WIDTH = 100; + private static final Integer DEFAULT_IMAGE_HEIGHT = 40; private final RedisTemplate redisTemplate; @Override public Mono handle(ServerRequest serverRequest) { - final String randomStr = serverRequest.queryParam("randomStr").get(); + ArithmeticCaptcha captcha = new ArithmeticCaptcha(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT); - return ServerResponse.status(HttpStatus.OK).contentType(MediaType.IMAGE_JPEG) - .body(BodyInserters.fromDataBuffers(Mono.create(monoSink -> { - try { - byte[] bytes = createCodeImage(randomStr); - DefaultDataBuffer dataBuffer = new DefaultDataBufferFactory().wrap(bytes); + String result = captcha.text(); - monoSink.success(dataBuffer); - } - catch (IOException e) { - log.error("ImageIO write err", e); - monoSink.error(e); - } - }))); - } - - private byte[] createCodeImage(String randomStr) throws IOException { - // 生成验证码 - String text = producer.createText(); - BufferedImage image = producer.createImage(text); - - // 保存验证码信息 - redisTemplate.opsForValue().set(CommonConstants.DEFAULT_CODE_KEY + randomStr, text, 60, TimeUnit.SECONDS); + //保存验证码信息 + String randomStr = serverRequest.queryParam("randomStr").get(); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.opsForValue().set(CacheConstants.DEFAULT_CODE_KEY + randomStr, result + , SecurityConstants.CODE_TIME, TimeUnit.SECONDS); // 转换流信息写出 FastByteArrayOutputStream os = new FastByteArrayOutputStream(); - ImageIO.write(image, "jpeg", os); - return os.toByteArray(); - } + captcha.out(os); + return ServerResponse + .status(HttpStatus.OK) + .contentType(MediaType.IMAGE_JPEG) + .body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray()))); + } }