背景
注册-登录-修改密码⼀般需要发送验证码,但是容易被 攻击恶意调⽤什么是短信-邮箱轰炸机
手机短信轰炸机是批、循环给⼿机⽆限发送各种⽹ 站的注册验 证码短信的⽅法。 公司带来的损失
短信⼀条5分钱,如果被⼤盗刷⼤家⾃⼰计算 邮箱通知不⽤钱,但被⼤盗刷,带宽、连接等都被占⽤,导致⽆法正常使⽤ 如何避免⾃⼰的⽹站成为”⾁鸡“或者被刷呢
增加图形验证码(开发⼈员)单IP请求次数限制(开发⼈员)限制号码发送(⼀般短信提供商会做)攻防永远是有的,只过加⼤了攻击者的成本,ROI划不 过来⾃然就放弃了 Kaptcha 框架介绍
⾕歌开源的⼀个可⾼度配置的实⽤验证 码⽣成⼯具
验证码的字体/⼤⼩/颜⾊
验证码内容的范围(数字,字⺟,中⽂汉字!)
验证码图⽚的⼤⼩,边框,边框粗细,边框颜⾊
验证码的⼲扰线 验证码的样式(⻥眼样式、3D、普通 模糊)
添加依赖
com.baomidou kaptcha-spring-bootstarter1.0.0
配置类
@Configuration public class CaptchaConfig { @Bean @Qualifier("captchaProducer") public DefaultKaptcha kaptcha() { DefaultKaptcha kaptcha = new DefaultKaptcha(); Properties properties = new Properties(); //验证码个数 properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4"); //字体间隔 properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE,"8"); //⼲扰线颜⾊ //⼲扰实现类 properties.setProperty(Constants.KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise"); //图⽚样式 properties.setProperty(Constants.KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.WaterRipple"); //⽂字来源 properties.setProperty(Constants.KAPTCHA_TEXTPRODUCER_CHAR_STRING, "0123456789"); Config config = new Config(properties); kaptcha.setConfig(config); return kaptcha; } }实战
我的配置类
获取访问ip和生成MD5的工具类
public class CommonUtil { public static String getIpAddr(HttpServletRequest request) { String ipAddress = null; try { ipAddress = request.getHeader("xforwarded-for"); if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getHeader("WL-Proxy-Client-IP"); } if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) { ipAddress = request.getRemoteAddr(); if (ipAddress.equals("127.0.0.1")) { // 根据⽹卡取本机配置的IP InetAddress inet = null; try { inet = InetAddress.getLocalHost(); } catch (UnknownHostException e) { e.printStackTrace(); } ipAddress = inet.getHostAddress(); } } // 对于通过多个代理的情况,第⼀个IP为客户端真实IP,多个IP按照','分割 if (ipAddress != null && ipAddress.length() > 15) { // "***.***.***.***".length() // = 15 if (ipAddress.indexOf(",") > 0) { ipAddress = ipAddress.substring(0, ipAddress.indexOf(",")); } } } catch (Exception e) { ipAddress=""; } return ipAddress; } public static String MD5(String data) { try { java.security.MessageDigest md = MessageDigest.getInstance("MD5"); byte[] array = md.digest(data.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); } catch (Exception exception) { } return null; } }接口开发
@RestController @RequestMapping("/api/v1/captcha") public class CaptchaController { @Autowired private StringRedisTemplate stringRedisTemplate; @Autowired private Producer producer; @RequestMapping("get_captcha") public void getCaptcha(HttpServletRequest request, HttpServletResponse response){ String captchaText = producer.createText(); String key = getCaptchaKey(request); // 十分钟过期 stringRedisTemplate.opsForValue().set(key,captchaText,10, TimeUnit.MINUTES); BufferedImage image = producer.createImage(captchaText); ServletOutputStream outputStream=null; try { outputStream= response.getOutputStream(); ImageIO.write(image,"jpg",outputStream); outputStream.flush(); outputStream.close(); } catch (IOException e) { e.printStackTrace(); } } private String getCaptchaKey(HttpServletRequest request){ String ipAddr = CommonUtil.getIpAddr(request); // 请求头 String userAgent=request.getHeader("user-Agent"); String key="user_service:captcha:"+CommonUtil.MD5(ipAddr+userAgent); return key; } }配置文件
server: port: 8080 spring: redis: host: redis锁在的ip password: redis的密码 port: 端口号 lettuce: pool: # 连接池最⼤连接数(使⽤负值表示没有限制) max-idle: 10 # 连接池中的最⼤空闲连接 max-active: 10 # 连接池中的最⼩空闲连接 min-idle: 0 # 连接池最⼤阻塞等待时间(使⽤负值表示没有限制) max-wait: -1ms结果
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)