🔖 v1.2.3
This commit is contained in:
1 parent
f185add546
commit
2b1255e7e4
4 files changed
-294
No files matched your search
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* 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.pigx.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 2017-12-21 21:12:18
|
||||
*/
|
||||
@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";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码宽度
|
||||
*/
|
||||
String DEFAULT_IMAGE_WIDTH = "100";
|
||||
|
||||
/**
|
||||
* 默认生成图像验证码高度
|
||||
*/
|
||||
String DEFAULT_IMAGE_HEIGHT = "40";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码长度
|
||||
*/
|
||||
String DEFAULT_IMAGE_LENGTH = "4";
|
||||
|
||||
/**
|
||||
* 默认生成图形验证码过期时间
|
||||
*/
|
||||
int DEFAULT_IMAGE_EXPIRE = 60;
|
||||
/**
|
||||
* 边框颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue.
|
||||
*/
|
||||
String DEFAULT_COLOR_FONT = "black";
|
||||
|
||||
/**
|
||||
* 图片边框
|
||||
*/
|
||||
String DEFAULT_IMAGE_BORDER = "no";
|
||||
/**
|
||||
* 默认图片间隔
|
||||
*/
|
||||
String DEFAULT_CHAR_SPACE = "5";
|
||||
|
||||
/**
|
||||
* 默认保存code的前缀
|
||||
*/
|
||||
String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY";
|
||||
/**
|
||||
* 验证码文字大小
|
||||
*/
|
||||
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;
|
||||
}
|
||||
}
|
||||
-25
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* 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.pigx.gateway.exception;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
*/
|
||||
public class ValidateCodeException extends Exception {
|
||||
|
||||
}
|
||||
-93
@@ -1,93 +0,0 @@
|
||||
package com.pig4cloud.pigx.gateway.filter;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.pig4cloud.pigx.gateway.exception.ValidateCodeException;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.gateway.filter.GatewayFilter;
|
||||
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.server.reactive.ServerHttpRequest;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author lengleng
|
||||
* @date 2018/7/4
|
||||
* 验证码处理
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ImageCodeGatewayFilter extends AbstractGatewayFilterFactory {
|
||||
private static final String OAUTH_TOKEN_URL = "/oauth/token";
|
||||
public static final String DEFAULT_CODE_KEY = "DEFAULT_CODE_KEY";
|
||||
|
||||
@Autowired
|
||||
private RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public GatewayFilter apply(Object config) {
|
||||
return (exchange, chain) -> {
|
||||
ServerHttpRequest request = exchange.getRequest();
|
||||
|
||||
// 不是登录请求,直接向下执行
|
||||
if (!StrUtil.containsAnyIgnoreCase(request.getURI().getPath(), OAUTH_TOKEN_URL)) {
|
||||
return chain.filter(exchange);
|
||||
}
|
||||
try {
|
||||
checkCode(request);
|
||||
} catch (ValidateCodeException e) {
|
||||
ServerHttpResponse response = exchange.getResponse();
|
||||
response.setStatusCode(HttpStatus.PRECONDITION_REQUIRED);
|
||||
return response.setComplete();
|
||||
}
|
||||
|
||||
return chain.filter(exchange);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 检查code
|
||||
*
|
||||
* @param request
|
||||
* @throws ValidateCodeException 校验异常
|
||||
*/
|
||||
private void checkCode(ServerHttpRequest request) throws ValidateCodeException {
|
||||
String code = request.getQueryParams().getFirst("code");
|
||||
|
||||
if (StrUtil.isBlank(code)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String randomStr = request.getQueryParams().getFirst("randomStr");
|
||||
if (StrUtil.isBlank(randomStr)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String key = DEFAULT_CODE_KEY + randomStr;
|
||||
if (!redisTemplate.hasKey(key)) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
Object codeObj = redisTemplate.opsForValue().get(key);
|
||||
|
||||
if (codeObj == null) {
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
String saveCode = codeObj.toString();
|
||||
if (StrUtil.isBlank(saveCode)) {
|
||||
redisTemplate.delete(key);
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
if (!StrUtil.equals(saveCode, code)) {
|
||||
redisTemplate.delete(key);
|
||||
throw new ValidateCodeException();
|
||||
}
|
||||
|
||||
redisTemplate.delete(key);
|
||||
}
|
||||
}
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* 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.pigx.gateway.handle;
|
||||
|
||||
import com.google.code.kaptcha.Producer;
|
||||
import com.pig4cloud.pigx.gateway.filter.ImageCodeGatewayFilter;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.FastByteArrayOutputStream;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import org.springframework.web.reactive.function.server.HandlerFunction;
|
||||
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 2018/7/5
|
||||
* 验证码生成逻辑处理类
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@AllArgsConstructor
|
||||
public class ImageCodeHandler implements HandlerFunction<ServerResponse> {
|
||||
private final Producer producer;
|
||||
private final RedisTemplate redisTemplate;
|
||||
|
||||
@Override
|
||||
public Mono<ServerResponse> handle(ServerRequest serverRequest) {
|
||||
//生成验证码
|
||||
String text = producer.createText();
|
||||
BufferedImage image = producer.createImage(text);
|
||||
|
||||
//保存验证码信息
|
||||
String randomStr = serverRequest.queryParam("randomStr").get();
|
||||
redisTemplate.opsForValue().set(ImageCodeGatewayFilter.DEFAULT_CODE_KEY + randomStr, text, 60, TimeUnit.SECONDS);
|
||||
|
||||
// 转换流信息写出
|
||||
FastByteArrayOutputStream os = new FastByteArrayOutputStream();
|
||||
try {
|
||||
ImageIO.write(image, "jpeg", os);
|
||||
} catch (IOException e) {
|
||||
log.error("ImageIO write err", e);
|
||||
return Mono.error(e);
|
||||
}
|
||||
|
||||
return ServerResponse
|
||||
.status(HttpStatus.OK)
|
||||
.contentType(MediaType.IMAGE_JPEG)
|
||||
.body(BodyInserters.fromResource(new ByteArrayResource(os.toByteArray())));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user