Introducing new features. closed #I1P8ZX 验证码调整为EasyCaptcha

This commit is contained in:
冷冷 2020-07-29 11:56:00 +08:00
parent 38802bfdf5
commit 6b36006685
4 changed files with 47 additions and 159 deletions

View File

@ -68,8 +68,8 @@ public interface SecurityConstants {
* sys_oauth_client_details 表的字段不包括client_idclient_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;
}

View File

@ -1,100 +0,0 @@
/*
*
* * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com).
* * <p>
* * 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
* * <p>
* * https://www.gnu.org/licenses/lgpl.html
* * <p>
* * 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;
}
}

View File

@ -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("验证码不合法");
}

View File

@ -1,30 +1,30 @@
/*
* Copyright (c) 2018-2025, lengleng All rights reserved.
*
* * Copyright (c) 2019-2020, 冷冷 (wangiegie@gmail.com).
* * <p>
* * 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
* * <p>
* * https://www.gnu.org/licenses/lgpl.html
* * <p>
* * 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<ServerResponse> {
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<ServerResponse> 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())));
}
}