今天主要写三个接口
1.获取图形验证码;
2.获取短信验证码;
3.注册信息入库;
1.获取图形验证码思路;
思路:
1.通过前端传过来的uuid,把uuid当作key;
2.通过工具类,生成随机四位正整数,当作value;
3.把uuid和四位整数存入redis;
4.四位图形base64编码验证码返回给前端;
@Override public JSONResult getVerifycode(String code) { //1.入参校验,code不能为空 //2.调用工具类生成随机四位数图形验证码 //3.把uuid作为key,四位数图形码作为value存入redis //4.返回base64编码给前端 if(!StringUtils.hasLength(code)){ throw new MyException("图形验证码不可为空"); } String f4 = MyTools.getRandomNum(4); String s = VerifyCodeUtils.verifyCode(120, 35, f4); redisTemplate.opsForValue().set(code,f4,1, TimeUnit.MINUTES); return JSONResult.success(s); }
2.获取短信验证码;
思路步骤:
1.首先入参校验,判断手机号和图形验证码不能为空;
2.再通过前端传过来的uuid,从redis中的去取图形验证码;
3.再比对图片验证码的正确;
4.比对手机号是否注册过;
5.发送短信验证码(6位数);
6.把手机号当作key,验证码当做value,存入redis;
1.首先入参校验,判断手机号和图形验证码不能为空;
if(!StringUtils.hasLength(dto.getImageCode())){ throw new MyException("验证码不可为空"); } if(!StringUtils.hasLength(dto.getMobile())){ throw new MyException("手机号不可为空"); }
2.再通过前端传过来的uuid,从redis中的去取图形验证码;
3.再比对图片验证码的正确;
String uuidValue = (String)redisTemplate.opsForValue().get(dto.getImageCodeKey()); if(!StringUtils.hasLength(uuidValue)){ throw new MyException("图形验证码过期了"); } if(!dto.getImageCode().equalsIgnoreCase(uuidValue)){ throw new MyException("图形验证码错误"); }
4.比对手机号是否注册过;
EntityWrapper<VipUser> wrapper = new EntityWrapper<>(); wrapper.eq("phone",dto.getMobile()); List<VipUser> vipUsers = vipUserMapper.selectList(wrapper); if(!CollectionUtils.isEmpty(vipUsers)){ throw new MyException("手机号已被注册"); }
5.发送短信验证码(6位数);
String f6 = MyTools.getRandomNum(6); System.out.println(f6);
6.把手机号当作key,验证码当做value,存入redis;
redisTemplate.opsForValue().set(dto.getMobile(),f6,2,TimeUnit.MINUTES);
3.注册信息入库;
思路步骤:
1.入参校验,判断手机号不能为空,密码不能为空,图形验证码不能为空,短信验证码不能为空;
2.通过前端传过来的手机号比对数据库中是否存在,是否注册过;
3.通过前端传过来的短信验证码,比对从redis中取出来的短信验证码;
4.再把注册信息入库;
1.入参校验,判断手机号不能为空,密码不能为空,图形验证码不能为空,短信验证码不能为空;
if(!StringUtils.hasLength(dto.getMobile())){ throw new MyException("手机号不可为空"); } if(!StringUtils.hasLength(dto.getImageCode())){ throw new MyException("验证码不可为空"); } if(!StringUtils.hasLength(dto.getPassword())){ throw new MyException("密码不可为空"); } if(!StringUtils.hasLength(dto.getSmsCode())){ throw new MyException("验证码不可为空"); }
2.通过前端传过来的手机号比对数据库中是否存在,是否注册过;
EntityWrapper<VipUser> wrapper = new EntityWrapper<>(); wrapper.eq("phone",dto.getMobile()); List<VipUser> vipUsers = vipUserMapper.selectList(wrapper); if(!CollectionUtils.isEmpty(vipUsers)){ throw new MyException("手机号已被注册"); }
3.通过前端传过来的短信验证码,比对从redis中取出来的短信验证码;
String phoneValue = (String)redisTemplate.opsForValue().get(dto.getMobile()); if(!dto.getSmsCode().equalsIgnoreCase(phoneValue)){ throw new MyException("短信验证码不正确"); }
4.再把注册信息入库;
//走到这里说明验证都正确,把信息入库 VipUser vipUser = new VipUser(); vipUser.setPhone(dto.getMobile()); vipUser.setCreateTime(new Date()); vipUser.setPassword(SecureUtil.md5(dto.getPassword())); vipUserMapper.insert(vipUser); return JSONResult.success();
需要用到的发短信的工具类:
public class MyTools { /** * @Description: 获取指定位数的随机整数 */ public synchronized static String getRandomNum(int num) { Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 1; i <= num; i++) { sb.append(random.nextInt(9)); } return sb.toString(); } }
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(); } /** * 输出指定验证码图片流 * */ 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); } } } /**获取随机验证码及其加密图片 * @param w 宽度 * @param h 长度 * @param size 验证码长度 */ public static String verifyCode(int w, int h, int size) throws IOException { //base64编码器 BASE64Encoder encoder = new BASE64Encoder(); //生成的图片验证码的值 String code = generateVerifyCode(size).toLowerCase(); ByteArrayOutputStream data = new ByteArrayOutputStream(); outputImage(w, h, data, code); return encoder.encode(data.toByteArray()); } /** * 获取随机验证码及其加密图片 * @param w 宽度 * @param h 长度 * @param code 验证码内容 */ public static String verifyCode(int w, int h, String code) { //base64编码器 BASE64Encoder encoder = new BASE64Encoder(); //输出流:输出图片的 ByteArrayOutputStream data = new ByteArrayOutputStream(); try { //把code合并到图片,并输出成流到 ByteArrayOutputStream outputImage(w, h, data, code); } catch (IOException e) { e.printStackTrace(); throw new MyException("图片验证码创建失败"); } //使用BASE64Encoder编码器把 ByteArrayOutputStream流中的图片内容基于base64编码成字符串,返回 return encoder.encode(data.toByteArray()); } public static void main(String[] args) throws Exception{ System.out.println(verifyCode(100, 30, 6)); } }