tudc 4 anos atrás
pai
commit
5f7ab1c26d

+ 24 - 0
tianhu-system/src/main/java/com/tianhu/system/common/ValidateCodeService.java

@@ -0,0 +1,24 @@
+package com.tianhu.system.common;
+
+import com.tianhu.common.core.exception.CaptchaException;
+import com.tianhu.common.core.web.domain.AjaxResult;
+
+import java.io.IOException;
+
+/**
+ * 验证码处理
+ * 
+ * @author tianhu
+ */
+public interface ValidateCodeService
+{
+    /**
+     * 生成验证码
+     */
+    public AjaxResult createCapcha() throws IOException, CaptchaException;
+
+    /**
+     * 校验验证码
+     */
+    public void checkCapcha(String key, String value, boolean clear) throws CaptchaException;
+}

+ 111 - 0
tianhu-system/src/main/java/com/tianhu/system/common/impl/ValidateCodeServiceImpl.java

@@ -0,0 +1,111 @@
+package com.tianhu.system.common.impl;
+
+import com.google.code.kaptcha.Producer;
+import com.tianhu.common.core.constant.Constants;
+import com.tianhu.common.core.exception.CaptchaException;
+import com.tianhu.common.core.utils.IdUtils;
+import com.tianhu.common.core.utils.StringUtils;
+import com.tianhu.common.core.utils.sign.Base64;
+import com.tianhu.common.core.web.domain.AjaxResult;
+import com.tianhu.common.redis.service.RedisService;
+import com.tianhu.system.common.ValidateCodeService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.util.FastByteArrayOutputStream;
+
+import javax.annotation.Resource;
+import javax.imageio.ImageIO;
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 验证码实现处理
+ *
+ * @author tianhu
+ */
+@Service
+public class ValidateCodeServiceImpl implements ValidateCodeService
+{
+    @Resource(name = "captchaProducer")
+    private Producer captchaProducer;
+
+    @Resource(name = "captchaProducerMath")
+    private Producer captchaProducerMath;
+
+    @Autowired
+    private RedisService redisService;
+
+    // 验证码类型
+    private String captchaType = "math";
+
+    /**
+     * 生成验证码
+     */
+    @Override
+    public AjaxResult createCapcha() throws IOException, CaptchaException
+    {
+        // 保存验证码信息
+        String uuid = IdUtils.simpleUUID();
+        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+
+        String capStr = null, code = null;
+        BufferedImage image = null;
+
+        // 生成验证码
+        if ("math".equals(captchaType))
+        {
+            String capText = captchaProducerMath.createText();
+            capStr = capText.substring(0, capText.lastIndexOf("@"));
+            code = capText.substring(capText.lastIndexOf("@") + 1);
+            image = captchaProducerMath.createImage(capStr);
+        }
+        else if ("char".equals(captchaType))
+        {
+            capStr = code = captchaProducer.createText();
+            image = captchaProducer.createImage(capStr);
+        }
+
+        redisService.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
+        // 转换流信息写出
+        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
+        try
+        {
+            ImageIO.write(image, "jpg", os);
+        }
+        catch (IOException e)
+        {
+            return AjaxResult.error(e.getMessage());
+        }
+
+        AjaxResult ajax = AjaxResult.success();
+        ajax.put("uuid", uuid);
+        ajax.put("img", Base64.encode(os.toByteArray()));
+        return ajax;
+    }
+
+    /**
+     * 校验验证码
+     */
+    @Override
+    public void checkCapcha(String code, String uuid, boolean clear) throws CaptchaException
+    {
+        if (StringUtils.isEmpty(code))
+        {
+            throw new CaptchaException("验证码不能为空");
+        }
+        if (StringUtils.isEmpty(uuid))
+        {
+            throw new CaptchaException("验证码已失效");
+        }
+        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
+        String captcha = redisService.getCacheObject(verifyKey);
+        if (clear) {
+            redisService.deleteObject(verifyKey);
+        }
+        if (!code.equalsIgnoreCase(captcha))
+        {
+            throw new CaptchaException("验证码错误");
+        }
+    }
+}

+ 85 - 0
tianhu-system/src/main/java/com/tianhu/system/config/properties/CaptchaConfig.java

@@ -0,0 +1,85 @@
+package com.tianhu.system.config.properties;
+
+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;
+
+import static com.google.code.kaptcha.Constants.*;
+
+/**
+ * 验证码配置
+ * 
+ * @author tianhu
+ */
+@Configuration
+public class CaptchaConfig
+{
+    @Bean(name = "captchaProducer")
+    public DefaultKaptcha getKaptchaBean()
+    {
+        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+        Properties properties = new Properties();
+        // 是否有边框 默认为true 我们可以自己设置yes,no
+        properties.setProperty(KAPTCHA_BORDER, "yes");
+        // 验证码文本字符颜色 默认为Color.BLACK
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
+        // 验证码图片宽度 默认为200
+        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
+        // 验证码图片高度 默认为50
+        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
+        // 验证码文本字符大小 默认为40
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
+        // KAPTCHA_SESSION_KEY
+        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
+        // 验证码文本字符长度 默认为5
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
+        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
+        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
+        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
+        Config config = new Config(properties);
+        defaultKaptcha.setConfig(config);
+        return defaultKaptcha;
+    }
+    
+    @Bean(name = "captchaProducerMath")
+    public DefaultKaptcha getKaptchaBeanMath()
+    {
+        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
+        Properties properties = new Properties();
+        // 是否有边框 默认为true 我们可以自己设置yes,no
+        properties.setProperty(KAPTCHA_BORDER, "yes");
+        // 边框颜色 默认为Color.BLACK
+        properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
+        // 验证码文本字符颜色 默认为Color.BLACK
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
+        // 验证码图片宽度 默认为200
+        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
+        // 验证码图片高度 默认为50
+        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
+        // 验证码文本字符大小 默认为40
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
+        // KAPTCHA_SESSION_KEY
+        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
+        // 验证码文本生成器
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.tianhu.gateway.config.KaptchaTextCreator");
+        // 验证码文本字符间距 默认为2
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
+        // 验证码文本字符长度 默认为5
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
+        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
+        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
+        // 验证码噪点颜色 默认为Color.BLACK
+        properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
+        // 干扰实现类
+        properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
+        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
+        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
+        Config config = new Config(properties);
+        defaultKaptcha.setConfig(config);
+        return defaultKaptcha;
+    }
+}