Le mot de passe d'inscription-Connexion-Changement nécessite généralement l'envoi d'un code de vérification, mais il est facile d'être attaqué et transféré de manière malveillante⽤
Qu'est-ce que SMS-Email Bomber
Le bombardier SMS mobile est un lot et cycle d'envoi illimité vers les téléphones mobiles Comment enregistrer le code de vérification SMS pour divers sites Web.
Perte causée par l'entreprise
Un message texte coûte 5 centimes s'il est volé par un gros voleur, vous pouvez calculer vous-même la notification gratuite par e-mail. Cependant, s'il est volé par un grand voleur, la bande passante, la connexion, etc. seront occupées, ce qui entraînera l'impossibilité de l'utiliser normalement
Comment empêcher votre site Web de devenir un « gril » ou d'être brossé ?
Ajouter un code de vérification graphique (développeurs)
Limiter le nombre de requêtes IP uniques (développeurs)
Restreindre l'envoi de numéros (les fournisseurs de SMS généraux le feront)
Il y a toujours une attaque et une défense, mais cela ne fait qu'augmenter le coût de l'attaquant, et le ROI n'en vaut pas la peine, alors nous avons abandonné
Un open source hautement configurable par Google Un outil pratique de génération de code de vérification
Police/taille/couleur du code de vérification
Gamme du contenu du code de vérification (chiffres, lettres, caractères chinois !)
Image du code de vérification⽚ taille, bordure, épaisseur de la bordure, couleur de la bordure
Style du code de vérification (style fisheye, 3D, flou normal)
Ajouter une dépendance
<!--kaptcha依赖包--> <dependency> <groupId>com.baomidou</groupId> <artifactId>kaptcha-spring-bootstarter</artifactId> <version>1.0.0</version> </dependency>
Classe de configuration
/** * 图像验证码的配置文件 * @author : look-word * @date : 2022-01-28 17:10 **/ @Configuration public class CaptchaConfig { /** * 验证码配置 * Kaptcha配置类名 * * @return */ @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; } }
Ma classe de configuration
Obtenir la classe d'outils pour accéder à IP et générer MD5
public class CommonUtil { /** * 获取ip * @param request * @return */ 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"); } request.getHeader("WL-Proxy-Client-IP"); 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.substring(0, ipAddress.indexOf(",")); } catch (Exception e) { ipAddress=""; } return ipAddress; } public static String MD5(String data) { 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; }
Développement d'interface
@RestController @RequestMapping("/api/v1/captcha") public class CaptchaController { @Autowired private StringRedisTemplate stringRedisTemplate; 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(); } } /** * 生成redis验证码模块的key * @param request * @return */ 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; }
Fichier de configuration
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
Résultats
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!