Maison  >  Article  >  base de données  >  Comment utiliser Springboot +redis+Kaptcha pour implémenter la fonction de code de vérification d'image

Comment utiliser Springboot +redis+Kaptcha pour implémenter la fonction de code de vérification d'image

WBOY
WBOYavant
2023-05-27 15:05:471051parcourir

Contexte

  • 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é

Introduction au framework Kaptcha

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;
    }
}

Combat réel

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按照&#39;,&#39;分割
            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

Comment utiliser Springboot +redis+Kaptcha pour implémenter la fonction de code de vérification dimage

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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer