|
|
@ -15,11 +15,14 @@
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
package org.opsli.core.utils;
|
|
|
|
package org.opsli.core.utils;
|
|
|
|
|
|
|
|
|
|
|
|
import com.google.code.kaptcha.Producer;
|
|
|
|
import cn.hutool.core.util.RandomUtil;
|
|
|
|
|
|
|
|
import com.google.common.collect.Lists;
|
|
|
|
|
|
|
|
import com.wf.captcha.ArithmeticCaptcha;
|
|
|
|
|
|
|
|
import com.wf.captcha.GifCaptcha;
|
|
|
|
|
|
|
|
import com.wf.captcha.SpecCaptcha;
|
|
|
|
|
|
|
|
import com.wf.captcha.base.Captcha;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
import org.opsli.common.constants.CacheConstants;
|
|
|
|
|
|
|
|
import org.opsli.common.exception.TokenException;
|
|
|
|
import org.opsli.common.exception.TokenException;
|
|
|
|
import org.opsli.common.utils.Props;
|
|
|
|
|
|
|
|
import org.opsli.core.cache.local.CacheUtil;
|
|
|
|
import org.opsli.core.cache.local.CacheUtil;
|
|
|
|
import org.opsli.core.msg.TokenMsg;
|
|
|
|
import org.opsli.core.msg.TokenMsg;
|
|
|
|
import org.opsli.plugins.redis.RedisPlugin;
|
|
|
|
import org.opsli.plugins.redis.RedisPlugin;
|
|
|
@ -28,10 +31,12 @@ import org.springframework.context.annotation.Lazy;
|
|
|
|
import org.springframework.core.annotation.Order;
|
|
|
|
import org.springframework.core.annotation.Order;
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
import org.springframework.stereotype.Component;
|
|
|
|
|
|
|
|
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
import java.io.OutputStream;
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
|
|
|
|
import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 验证码
|
|
|
|
* 验证码
|
|
|
|
*
|
|
|
|
*
|
|
|
@ -41,7 +46,16 @@ import static org.opsli.common.constants.OrderConstants.UTIL_ORDER;
|
|
|
|
@Component
|
|
|
|
@Component
|
|
|
|
@Order(UTIL_ORDER)
|
|
|
|
@Order(UTIL_ORDER)
|
|
|
|
@Lazy(false)
|
|
|
|
@Lazy(false)
|
|
|
|
public class CaptchaUtil{
|
|
|
|
public class CaptchaUtil {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** 验证码宽度 */
|
|
|
|
|
|
|
|
private static final int CAPTCHA_WIDTH = 180;
|
|
|
|
|
|
|
|
/** 验证码高度 */
|
|
|
|
|
|
|
|
private static final int CAPTCHA_HEIGHT = 58;
|
|
|
|
|
|
|
|
/** 验证码位数 */
|
|
|
|
|
|
|
|
private static final int CAPTCHA_LEN = 4;
|
|
|
|
|
|
|
|
/** 验证码策略 */
|
|
|
|
|
|
|
|
private static final List<CaptchaStrategy> CAPTCHA_STRATEGY_LIST;
|
|
|
|
|
|
|
|
|
|
|
|
/** 缓存前缀 */
|
|
|
|
/** 缓存前缀 */
|
|
|
|
private static final String PREFIX = "temp:captcha:";
|
|
|
|
private static final String PREFIX = "temp:captcha:";
|
|
|
@ -49,55 +63,69 @@ public class CaptchaUtil{
|
|
|
|
private static final int TIME_OUT = 300;
|
|
|
|
private static final int TIME_OUT = 300;
|
|
|
|
/** Redis插件 */
|
|
|
|
/** Redis插件 */
|
|
|
|
private static RedisPlugin redisPlugin;
|
|
|
|
private static RedisPlugin redisPlugin;
|
|
|
|
/** 谷歌验证码 */
|
|
|
|
|
|
|
|
private static Producer producer;
|
|
|
|
static {
|
|
|
|
|
|
|
|
CAPTCHA_STRATEGY_LIST = Lists.newArrayListWithCapacity(3);
|
|
|
|
|
|
|
|
CAPTCHA_STRATEGY_LIST.add(new CaptchaStrategyBySpec());
|
|
|
|
|
|
|
|
CAPTCHA_STRATEGY_LIST.add(new CaptchaStrategyByGif());
|
|
|
|
|
|
|
|
CAPTCHA_STRATEGY_LIST.add(new CaptchaStrategyByArithmetic());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 获得验证码
|
|
|
|
* 获得验证码
|
|
|
|
* @param uuid UUID
|
|
|
|
*
|
|
|
|
* @return BufferedImage
|
|
|
|
* @param uuid
|
|
|
|
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static BufferedImage getCaptcha(String uuid) {
|
|
|
|
public static void createCaptcha(String uuid, OutputStream out) {
|
|
|
|
if(StringUtils.isBlank(uuid)){
|
|
|
|
if (StringUtils.isBlank(uuid)) {
|
|
|
|
throw new RuntimeException("uuid不能为空");
|
|
|
|
throw new RuntimeException("uuid不能为空");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//生成文字验证码
|
|
|
|
// 随机生成验证码
|
|
|
|
String code = producer.createText();
|
|
|
|
int randomInt = RandomUtil.randomInt(0, CAPTCHA_STRATEGY_LIST.size());
|
|
|
|
|
|
|
|
|
|
|
|
boolean ret = redisPlugin.put(CacheUtil.getPrefixName() + PREFIX + uuid, code, TIME_OUT);
|
|
|
|
// 获得验证码生成策略
|
|
|
|
|
|
|
|
CaptchaStrategy captchaStrategy = CAPTCHA_STRATEGY_LIST.get(randomInt);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 生成验证码
|
|
|
|
|
|
|
|
Captcha captcha = captchaStrategy.createCaptcha();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 保存至缓存
|
|
|
|
|
|
|
|
boolean ret = redisPlugin.put(CacheUtil.getPrefixName() + PREFIX + uuid, captcha.text(), TIME_OUT);
|
|
|
|
if(ret){
|
|
|
|
if(ret){
|
|
|
|
return producer.createImage(code);
|
|
|
|
// 输出
|
|
|
|
|
|
|
|
captcha.out(out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 校验验证码
|
|
|
|
* 校验验证码
|
|
|
|
* @param uuid UUID
|
|
|
|
*
|
|
|
|
* @param code CODE
|
|
|
|
* @param uuid
|
|
|
|
|
|
|
|
* @param code
|
|
|
|
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static void validate(String uuid, String code) {
|
|
|
|
public static void validate(String uuid, String code) {
|
|
|
|
// 判断UUID 是否为空
|
|
|
|
// 判断UUID 是否为空
|
|
|
|
if(StringUtils.isEmpty(uuid)){
|
|
|
|
if (StringUtils.isEmpty(uuid)) {
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_UUID_NULL);
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_UUID_NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 判断 验证码是否为空
|
|
|
|
// 判断 验证码是否为空
|
|
|
|
if(StringUtils.isEmpty(code)){
|
|
|
|
if (StringUtils.isEmpty(code)) {
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_CODE_NULL);
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_CODE_NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证码
|
|
|
|
// 验证码
|
|
|
|
String codeTemp = (String) redisPlugin.get(CacheUtil.getPrefixName() + PREFIX + uuid);
|
|
|
|
String codeTemp = (String) redisPlugin.get(CacheUtil.getPrefixName() + PREFIX + uuid);
|
|
|
|
if(StringUtils.isEmpty(codeTemp)){
|
|
|
|
if (StringUtils.isEmpty(codeTemp)) {
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_NULL);
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 验证 验证码是否正确
|
|
|
|
// 验证 验证码是否正确
|
|
|
|
boolean captchaFlag = codeTemp.equalsIgnoreCase(code);
|
|
|
|
boolean captchaFlag = codeTemp.equalsIgnoreCase(code);
|
|
|
|
if(!captchaFlag){
|
|
|
|
if (!captchaFlag) {
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_ERROR);
|
|
|
|
throw new TokenException(TokenMsg.EXCEPTION_CAPTCHA_ERROR);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -105,11 +133,12 @@ public class CaptchaUtil{
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* 删除验证码
|
|
|
|
* 删除验证码
|
|
|
|
* @param uuid UUID
|
|
|
|
*
|
|
|
|
* @return boolean
|
|
|
|
* @param uuid
|
|
|
|
|
|
|
|
* @return
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public static boolean delCaptcha(String uuid) {
|
|
|
|
public static boolean delCaptcha(String uuid) {
|
|
|
|
if(StringUtils.isEmpty(uuid)){
|
|
|
|
if (StringUtils.isEmpty(uuid)) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -118,16 +147,61 @@ public class CaptchaUtil{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ==========================
|
|
|
|
// ==========================
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
@Autowired
|
|
|
|
public void setRedisPlugin(RedisPlugin redisPlugin) {
|
|
|
|
public void setRedisPlugin(RedisPlugin redisPlugin) {
|
|
|
|
CaptchaUtil.redisPlugin = redisPlugin;
|
|
|
|
CaptchaUtil.redisPlugin = redisPlugin;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@Autowired
|
|
|
|
|
|
|
|
public void setProducer(Producer producer) {
|
|
|
|
// ======================
|
|
|
|
CaptchaUtil.producer = producer;
|
|
|
|
|
|
|
|
|
|
|
|
public interface CaptchaStrategy{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 生成验证码对象
|
|
|
|
|
|
|
|
* @return Captcha
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
Captcha createCaptcha();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 数字英文混合验证码 静态
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private static class CaptchaStrategyBySpec implements CaptchaStrategy{
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Captcha createCaptcha() {
|
|
|
|
|
|
|
|
// 生成验证码
|
|
|
|
|
|
|
|
SpecCaptcha captcha = new SpecCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LEN);
|
|
|
|
|
|
|
|
captcha.setCharType(Captcha.TYPE_DEFAULT);
|
|
|
|
|
|
|
|
return captcha;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 数字英文混合验证码 动态
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private static class CaptchaStrategyByGif implements CaptchaStrategy{
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Captcha createCaptcha() {
|
|
|
|
|
|
|
|
// 生成验证码
|
|
|
|
|
|
|
|
GifCaptcha captcha = new GifCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_LEN);
|
|
|
|
|
|
|
|
captcha.setCharType(Captcha.TYPE_DEFAULT);
|
|
|
|
|
|
|
|
return captcha;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 算数验证码 动态
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private static class CaptchaStrategyByArithmetic implements CaptchaStrategy{
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
|
|
|
public Captcha createCaptcha() {
|
|
|
|
|
|
|
|
// 生成验证码
|
|
|
|
|
|
|
|
return new ArithmeticCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|