diff --git a/eladmin-system/pom.xml b/eladmin-system/pom.xml index 227c5859..909b74a8 100644 --- a/eladmin-system/pom.xml +++ b/eladmin-system/pom.xml @@ -15,22 +15,7 @@ 0.9.1 - - - jitpack.io - https://jitpack.io - - - - - - - com.github.whvcse - EasyCaptcha - 1.5.0 - - me.zhengjie eladmin-generator diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java index bca95fc9..b9362139 100644 --- a/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/rest/AuthenticationController.java @@ -12,6 +12,7 @@ import me.zhengjie.modules.security.security.AuthenticationInfo; import me.zhengjie.modules.security.security.AuthorizationUser; import me.zhengjie.modules.security.security.ImgResult; import me.zhengjie.modules.security.security.JwtUser; +import me.zhengjie.modules.security.utils.VerifyCodeUtils; import me.zhengjie.utils.EncryptUtils; import me.zhengjie.modules.security.utils.JwtTokenUtil; import me.zhengjie.utils.SecurityUtils; @@ -102,21 +103,16 @@ public class AuthenticationController { */ @GetMapping(value = "vCode") public ImgResult getCode(HttpServletResponse response) throws IOException { - // 三个参数分别为宽、高、位数 - SpecCaptcha specCaptcha = new SpecCaptcha(105, 33, 4); - - // 设置类型,纯数字、纯字母、字母数字混合 - specCaptcha.setCharType(Captcha.TYPE_DEFAULT); - - // 生成的验证码 - String code = specCaptcha.text(); + //生成随机字串 + String verifyCode = VerifyCodeUtils.generateVerifyCode(4); String uuid = IdUtil.simpleUUID(); - redisService.saveCode(uuid,code); - response.addHeader("codeUuid",uuid); + redisService.saveCode(uuid,verifyCode); + // 生成图片 + int w = 111, h = 36; ByteArrayOutputStream stream = new ByteArrayOutputStream(); + VerifyCodeUtils.outputImage(w, h, stream, verifyCode); try { - specCaptcha.out(stream); return new ImgResult(Base64.encode(stream.toByteArray()),uuid); } catch (Exception e) { e.printStackTrace(); diff --git a/eladmin-system/src/main/java/me/zhengjie/modules/security/utils/VerifyCodeUtils.java b/eladmin-system/src/main/java/me/zhengjie/modules/security/utils/VerifyCodeUtils.java new file mode 100644 index 00000000..e3beabd3 --- /dev/null +++ b/eladmin-system/src/main/java/me/zhengjie/modules/security/utils/VerifyCodeUtils.java @@ -0,0 +1,204 @@ +package me.zhengjie.modules.security.utils; + +import java.awt.Color; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.geom.AffineTransform; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.Random; +import javax.imageio.ImageIO; + +/** + * @author https://blog.csdn.net/ruixue0117/article/details/22829557 + * @date 2019-6-20 17:28:53 + */ +public class VerifyCodeUtils{ + + //使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符 + public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"; + private static Random random = new Random(); + + + /** + * 使用系统默认字符源生成验证码 + * @param verifySize 验证码长度 + * @return + */ + public static String generateVerifyCode(int verifySize){ + return generateVerifyCode(verifySize, VERIFY_CODES); + } + /** + * 使用指定源生成验证码 + * @param verifySize 验证码长度 + * @param sources 验证码字符源 + * @return + */ + public static String generateVerifyCode(int verifySize, String sources){ + if(sources == null || sources.length() == 0){ + sources = VERIFY_CODES; + } + int codesLen = sources.length(); + Random rand = new Random(System.currentTimeMillis()); + StringBuilder verifyCode = new StringBuilder(verifySize); + for(int i = 0; i < verifySize; i++){ + verifyCode.append(sources.charAt(rand.nextInt(codesLen-1))); + } + return verifyCode.toString(); + } + + /** + * 输出指定验证码图片流 + * @param w + * @param h + * @param os + * @param code + * @throws IOException + */ + public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{ + int verifySize = code.length(); + BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); + Random rand = new Random(); + Graphics2D g2 = image.createGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); + Color[] colors = new Color[5]; + Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, + Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, + Color.PINK, Color.YELLOW }; + float[] fractions = new float[colors.length]; + for(int i = 0; i < colors.length; i++){ + colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; + fractions[i] = rand.nextFloat(); + } + Arrays.sort(fractions); + + g2.setColor(Color.GRAY);// 设置边框色 + g2.fillRect(0, 0, w, h); + + Color c = getRandColor(200, 250); + g2.setColor(c);// 设置背景色 + g2.fillRect(0, 2, w, h-4); + + //绘制干扰线 + Random random = new Random(); + g2.setColor(getRandColor(160, 200));// 设置线条的颜色 + for (int i = 0; i < 20; i++) { + int x = random.nextInt(w - 1); + int y = random.nextInt(h - 1); + int xl = random.nextInt(6) + 1; + int yl = random.nextInt(12) + 1; + g2.drawLine(x, y, x + xl + 40, y + yl + 20); + } + + // 添加噪点 + float yawpRate = 0.05f;// 噪声率 + int area = (int) (yawpRate * w * h); + for (int i = 0; i < area; i++) { + int x = random.nextInt(w); + int y = random.nextInt(h); + int rgb = getRandomIntColor(); + image.setRGB(x, y, rgb); + } + + shear(g2, w, h, c);// 使图片扭曲 + + g2.setColor(getRandColor(100, 160)); + int fontSize = h-4; + Font font = new Font("Algerian", Font.ITALIC, fontSize); + g2.setFont(font); + char[] chars = code.toCharArray(); + for(int i = 0; i < verifySize; i++){ + AffineTransform affine = new AffineTransform(); + affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2); + g2.setTransform(affine); + g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10); + } + + g2.dispose(); + ImageIO.write(image, "jpg", os); + } + + private static Color getRandColor(int fc, int bc) { + if (fc > 255) + fc = 255; + if (bc > 255) + bc = 255; + int r = fc + random.nextInt(bc - fc); + int g = fc + random.nextInt(bc - fc); + int b = fc + random.nextInt(bc - fc); + return new Color(r, g, b); + } + + private static int getRandomIntColor() { + int[] rgb = getRandomRgb(); + int color = 0; + for (int c : rgb) { + color = color << 8; + color = color | c; + } + return color; + } + + private static int[] getRandomRgb() { + int[] rgb = new int[3]; + for (int i = 0; i < 3; i++) { + rgb[i] = random.nextInt(255); + } + return rgb; + } + + private static void shear(Graphics g, int w1, int h1, Color color) { + shearX(g, w1, h1, color); + shearY(g, w1, h1, color); + } + + private static void shearX(Graphics g, int w1, int h1, Color color) { + + int period = random.nextInt(2); + + boolean borderGap = true; + int frames = 1; + int phase = random.nextInt(2); + + for (int i = 0; i < h1; i++) { + double d = (double) (period >> 1) + * Math.sin((double) i / (double) period + + (6.2831853071795862D * (double) phase) + / (double) frames); + g.copyArea(0, i, w1, 1, (int) d, 0); + if (borderGap) { + g.setColor(color); + g.drawLine((int) d, i, 0, i); + g.drawLine((int) d + w1, i, w1, i); + } + } + + } + + private static void shearY(Graphics g, int w1, int h1, Color color) { + + int period = random.nextInt(40) + 10; // 50; + + boolean borderGap = true; + int frames = 20; + int phase = 7; + for (int i = 0; i < w1; i++) { + double d = (double) (period >> 1) + * Math.sin((double) i / (double) period + + (6.2831853071795862D * (double) phase) + / (double) frames); + g.copyArea(i, 0, 1, h1, 0, (int) d); + if (borderGap) { + g.setColor(color); + g.drawLine(i, (int) d, i, 0); + g.drawLine(i, (int) d + h1, i, h1); + } + + } + + } +} \ No newline at end of file diff --git a/eladmin-system/src/main/resources/template/generator/admin/Dto.ftl b/eladmin-system/src/main/resources/template/generator/admin/Dto.ftl index 63e5a9c7..d57910b4 100644 --- a/eladmin-system/src/main/resources/template/generator/admin/Dto.ftl +++ b/eladmin-system/src/main/resources/template/generator/admin/Dto.ftl @@ -24,9 +24,7 @@ public class ${className}DTO implements Serializable { <#list columns as column> <#if column.columnComment != ''> - /** - * ${column.columnComment} - */ + // ${column.columnComment} <#if column.columnKey = 'PRI'> <#if !auto && pkColumnType = 'Long'> diff --git a/eladmin-system/src/main/resources/template/generator/admin/Entity.ftl b/eladmin-system/src/main/resources/template/generator/admin/Entity.ftl index 85583c08..195c40e3 100644 --- a/eladmin-system/src/main/resources/template/generator/admin/Entity.ftl +++ b/eladmin-system/src/main/resources/template/generator/admin/Entity.ftl @@ -22,9 +22,7 @@ public class ${className} implements Serializable { <#list columns as column> <#if column.columnComment != ''> - /** - * ${column.columnComment} - */ + // ${column.columnComment} <#if column.columnKey = 'PRI'> @Id