pom.xml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/framework/config/CaptchaConfig.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/project/common/CaptchaController.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/resources/application.yml | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
pom.xml
@@ -31,6 +31,7 @@ <commons.fileupload.version>1.3.3</commons.fileupload.version> <bitwalker.version>1.19</bitwalker.version> <jwt.version>0.9.0</jwt.version> <kaptcha.version>2.3.2</kaptcha.version> <swagger.version>2.9.2</swagger.version> <poi.version>3.17</poi.version> <oshi.version>3.9.1</oshi.version> @@ -243,6 +244,19 @@ </exclusion> </exclusions> </dependency> <!--éªè¯ç --> <dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>${kaptcha.version}</version> <exclusions> <exclusion> <artifactId>javax.servlet-api</artifactId> <groupId>javax.servlet</groupId> </exclusion> </exclusions> </dependency> </dependencies> src/main/java/com/ruoyi/framework/config/CaptchaConfig.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,83 @@ package com.ruoyi.framework.config; import java.util.Properties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.google.code.kaptcha.impl.DefaultKaptcha; import com.google.code.kaptcha.util.Config; import static com.google.code.kaptcha.Constants.*; /** * éªè¯ç é ç½® * * @author ruoyi */ @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.ruoyi.framework.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; } } src/main/java/com/ruoyi/framework/config/KaptchaTextCreator.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,75 @@ package com.ruoyi.framework.config; import java.util.Random; import com.google.code.kaptcha.text.impl.DefaultTextCreator; /** * éªè¯ç ææ¬çæå¨ * * @author ruoyi */ public class KaptchaTextCreator extends DefaultTextCreator { private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(","); @Override public String getText() { Integer result = 0; Random random = new Random(); int x = random.nextInt(10); int y = random.nextInt(10); StringBuilder suChinese = new StringBuilder(); int randomoperands = (int) Math.round(Math.random() * 2); if (randomoperands == 0) { result = x * y; suChinese.append(CNUMBERS[x]); suChinese.append("*"); suChinese.append(CNUMBERS[y]); } else if (randomoperands == 1) { if (!(x == 0) && y % x == 0) { result = y / x; suChinese.append(CNUMBERS[y]); suChinese.append("/"); suChinese.append(CNUMBERS[x]); } else { result = x + y; suChinese.append(CNUMBERS[x]); suChinese.append("+"); suChinese.append(CNUMBERS[y]); } } else if (randomoperands == 2) { if (x >= y) { result = x - y; suChinese.append(CNUMBERS[x]); suChinese.append("-"); suChinese.append(CNUMBERS[y]); } else { result = y - x; suChinese.append(CNUMBERS[y]); suChinese.append("-"); suChinese.append(CNUMBERS[x]); } } else { result = x + y; suChinese.append(CNUMBERS[x]); suChinese.append("+"); suChinese.append(CNUMBERS[y]); } suChinese.append("=?@" + result); return suChinese.toString(); } } src/main/java/com/ruoyi/project/common/CaptchaController.java
@@ -1,15 +1,19 @@ package com.ruoyi.project.common; import java.io.ByteArrayOutputStream; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.concurrent.TimeUnit; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.util.FastByteArrayOutputStream; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.google.code.kaptcha.Producer; import com.ruoyi.common.constant.Constants; import com.ruoyi.common.utils.IdUtils; import com.ruoyi.common.utils.VerifyCodeUtils; import com.ruoyi.common.utils.sign.Base64; import com.ruoyi.framework.redis.RedisCache; import com.ruoyi.framework.web.domain.AjaxResult; @@ -22,8 +26,19 @@ @RestController public class CaptchaController { @Resource(name = "captchaProducer") private Producer captchaProducer; @Resource(name = "captchaProducerMath") private Producer captchaProducerMath; @Autowired private RedisCache redisCache; // éªè¯ç ç±»å @Value("${ruoyi.captchaType}") private String captchaType; /** * çæéªè¯ç @@ -31,32 +46,42 @@ @GetMapping("/captchaImage") public AjaxResult getCode(HttpServletResponse response) throws IOException { // çæéæºå串 String verifyCode = VerifyCodeUtils.generateVerifyCode(4); // å¯ä¸æ è¯ // ä¿åéªè¯ç ä¿¡æ¯ String uuid = IdUtils.simpleUUID(); String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; redisCache.setCacheObject(verifyKey, verifyCode, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); // çæå¾ç int w = 111, h = 36; ByteArrayOutputStream stream = new ByteArrayOutputStream(); VerifyCodeUtils.outputImage(w, h, stream, verifyCode); 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); } redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); // è½¬æ¢æµä¿¡æ¯ååº FastByteArrayOutputStream os = new FastByteArrayOutputStream(); try { AjaxResult ajax = AjaxResult.success(); ajax.put("uuid", uuid); ajax.put("img", Base64.encode(stream.toByteArray())); return ajax; ImageIO.write(image, "jpg", os); } catch (Exception e) catch (IOException e) { e.printStackTrace(); return AjaxResult.error(e.getMessage()); } finally { stream.close(); } AjaxResult ajax = AjaxResult.success(); ajax.put("uuid", uuid); ajax.put("img", Base64.encode(os.toByteArray())); return ajax; } } src/main/resources/application.yml
@@ -12,6 +12,8 @@ profile: D:/ruoyi/uploadPath # è·åipå°åå¼å ³ addressEnabled: false # éªè¯ç ç±»å math æ°ç»è®¡ç® char å符éªè¯ captchaType: math # å¼åç¯å¢é ç½® server: