Introduire la boîte aux lettres QQ pour envoyer le code de vérification pour la vérification de sécurité

Autres solutions => Introduire un service SMS pour envoyer le code de vérification du téléphone mobile pour la vérification de la sécurité.
L'opération est relativement compliquée et payante. Des tutoriels détaillés sont disponibles pour référence.

Récemment, je souhaite ajouter des contrôles de sécurité à mon projet lors de mon inscription. Je voulais à l'origine utiliser le code de vérification par SMS, mais je ne peux que reculer et utiliser la boîte aux lettres QQ pour vérifier l'inscription ~

1. Analyse de la demande

  • Scénario : L'utilisateur saisit son e-mail, clique pour obtenir le code de vérification, et l'arrière-plan enverra un e-mail à l'e-mail correspondant.

  • Analyse : Pour éviter de saturer les boîtes aux lettres, vous pouvez limiter l'accès à une seule fois par minute.

    • Frontend : désactivez le bouton bouton dans le délai imparti.
    • Backend : stocker dans redis pour définir le délai d'expiration et demander de déterminer d'abord s'il y a des données dans redis.

2. Préparation de l'environnement

(1) Environnement de boîte aux lettres

Ouvrez le service SMTP dans la boîte aux lettres QQ et obtenez le code d'autorisation

  1. Version Web : entrez dans la boîte aux lettres, cliquez sur le compte dans les paramètres
    insérez la description de l'image ici

  2. Faites défiler vers le bas pour voir le commutateur de service suivant, cliquez pour ouvrir
    Veuillez ajouter une description de l'image

Après avoir cliqué sur Ouvrir, vous obtiendrez une chaîne de codes d'autorisation, qui doivent être utilisés dans le programme principal.

  1. Il peut être nécessaire de compléter la vérification de sécurité pertinente
    insérez la description de l'image ici

(2) Environnement principal

La probabilité élevée est utilisée dans les projets Web, nous créons donc un projet SpringBoot

  1. Après avoir créé le projet, importez le package jar requis pour faire fonctionner la boîte aux lettres dans le fichier pom
        <!--QQ邮箱验证码所需jar包-->
        <dependency>
            <groupId>javax.activation</groupId>
            <artifactId>activation</artifactId>
            <version>1.1.1</version>
        </dependency>

        <dependency>
            <groupId>javax.mail</groupId>
            <artifactId>mail</artifactId>
            <version>1.4.7</version>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-email</artifactId>
            <version>1.4</version>
        </dependency>
  1. Comme nous devons utiliser le code de vérification du cache redis dans le projet de printemps, nous devons également importer le package jar redis
   <!--     使用redis缓存验证码时效-->
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
  1. Configurez redis dans le fichier yml, définissez le mot de passe redis et n'oubliez pas d'ajouter la configuration du mot de passe
spring:
  redis:
    # redis数据库索引(默认为0),我们使用索引为3的数据库,避免和其他数据库冲突
    database: 3
    # redis服务器地址(默认为localhost)
    host: localhost
    # redis端口(默认为6379)
    port: 6379

3. Programme principal

(1) Réalisation de l'effet

  1. L'envoi d'e-mails doit être considéré comme un outil, nous pouvons donc écrire le code suivant dans la classe d'outils
package com.example.utils;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;


public class SendMailUtil {
    
    

    /**
     * 发送邮件代码
     *
     * @param targetEmail 目标用户邮箱
     * @param authCode    发送的验证码
     */
    public static void sendEmailCode(String targetEmail, String authCode) {
    
    
        try {
    
    
            // 创建邮箱对象
            SimpleEmail mail = new SimpleEmail();
            // 设置发送邮件的服务器
            mail.setHostName("smtp.qq.com");
            // "你的邮箱号"+ "上文开启SMTP获得的授权码"
            mail.setAuthentication("[email protected]", "fbsxxxxxsijdj");
            // 发送邮件 "你的邮箱号"+"发送时用的昵称"
            mail.setFrom("[email protected]", "观止");
            // 使用安全链接
            mail.setSSLOnConnect(true);
            // 接收用户的邮箱
            mail.addTo(targetEmail);
            // 邮件的主题(标题)
            mail.setSubject("注册验证码");
            // 邮件的内容
            mail.setMsg("您的验证码为:" + authCode+"(一分钟内有效)");
            // 发送
            mail.send();
        } catch (EmailException e) {
    
    
            e.printStackTrace();
        }
    }
}
  1. Écrivez l'interface suivante
@RestController
public class SendMail {
    
    

    @PostMapping("/getCode")
    @ResponseBody
    public String mail(@RequestParam("targetEmail") String targetEmail) {
    
    
        // 随机生成六位数验证码
        String authCode = String.valueOf(new Random().nextInt(899999) + 100000);
        SendMailUtil.sendEmailCode(targetEmail,authCode);
        return "ok";
    }
}

  1. Testons l'interface
GET http://localhost:8080/[email protected]

Vous pouvez voir les effets suivants :
insérez la description de l'image ici

De cette façon, notre effet initial a été réalisé ~

(3) Amélioration du cache

Dans le programme ci-dessus, on peut envoyer des mails tout le temps en envoyant des requêtes de façon folle. Ce n'est évidemment pas ce à quoi on s'attendait. Ensuite, on va ajouter redis pour l'améliorer.

@RestController
public class SendMail {
    
    
    @Resource
    private RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();

    /**
     * @param targetEmail 用户邮箱
     * @return
     */
    @GetMapping("/getCode")
    @ResponseBody
    public String mail(@RequestParam("targetEmail") String targetEmail) {
    
    
        // 发送前先看下我们是否已经缓存了验证码
        String yzm = redisTemplate.opsForValue().get("yzm");
        // 判断是否存在
        if (yzm == null){
    
    
            // 生成六位数验证码
            int authNum = new Random().nextInt(899999) + 100000;
            String authCode = String.valueOf(authNum);
            // 不存在,我们发送邮箱给用户
            SendMailUtil.sendEmailCode(targetEmail, "你的验证码为:" + authCode + "(五分钟内有效)");
            // 存入redis中,设置有效期为1分钟
            redisTemplate.opsForValue().set("yzm", authCode, 1, TimeUnit.MINUTES);
            return "发送成功";
        }
        // 存在,直接返回,不再发送邮箱~
        return "请勿重复发送验证码";
    }
   }

Après avoir testé à nouveau de cette manière, on peut constater que le clic fou n'a plus aucun effet, et il a été intercepté avec succès, ce qui est tellement plus sûr
insérez la description de l'image ici

À ce stade, l'effet que nous voulions au début a été réalisé dans la petite démo, puis nous pouvons présenter notre propre projet officiel

4. Problèmes de déploiement en ligne

Selon le code ci-dessus, il s'exécute normalement localement, mais s'il est déployé dans l'environnement en ligne, l'erreur suivante se produit :

1.Sending the email to the following server failed : smtp.163.com:465
2.Could not connect to SMTP host: smtp.163.com, port: 465
3.No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

Raison : les fabricants de serveurs tels qu'Alibaba Cloud ont désactivé le port par défaut 25. Nous devons utiliser les ports disponibles tels que 465 pour envoyer des e-mails et activer les connexions SSL, et effectuer les configurations associées suivantes. Enfin, ouvrez la fenêtre correspondante sur le pare-feu du serveur.

/**
 * 验证获取操作安全证书
 */
public class CheckCodeUtils {
    
    


    /**
     * 发送邮件代码
     *
     * @param targetEmail 目标用户邮箱
     * @param authCode    发送的验证码
     */
    public static String GetEmailCode(String targetEmail, String authCode) {
    
    
        try {
    
    
            // 创建邮箱对象
            SimpleEmail mail = new SimpleEmail();
            // 设置发送邮件的服务器
            mail.setHostName("smtp.qq.com");
            // "你的邮箱号"+ "上文开启SMTP获得的授权码"
            mail.setAuthentication("[email protected]", "GHNUxxxxxVL");
            // 发送邮件 "你的邮箱号"+"发送时用的昵称"
            mail.setFrom("[email protected]", "伙伴匹配系统");
            // 发送服务端口
            mail.setSslSmtpPort(String.valueOf(465));
            // 使用安全链接
            mail.setSSLOnConnect(true);
            System.setProperty("mail.smtp.ssl.enable", "true");
            System.setProperty("mail.smtp.ssl.protocols", "TLSv1.2");
            // 接收用户的邮箱
            mail.addTo(targetEmail);
            // 邮件的主题(标题)
            mail.setSubject("注册验证码");
            // 邮件的内容
            mail.setMsg("【伙伴匹配系统】您的验证码为:" + authCode + "(5分钟内有效)");
            // 发送
            mail.send();
            return "发送成功,请注意查收";
        } catch (EmailException e) {
    
    
            return e.getMessage();
        }
    }
}

Cinq. Avant (supplément)

J'ai simplement écrit une interface avec du js natif, vous pouvez jeter un oeil si ça vous intéresse
insérez la description de l'image ici

code afficher comme ci-dessous:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div>
    <input id="mail" type="text">
    <button id="getCode">获取验证码</button>
</div>
<script>

    /*按钮禁用60秒,并显示倒计时*/
    function disabledButton() {
      
      
        const getCode = document.querySelector("#getCode")
        getCode.disabled = true
        let second = 60;
        const intervalObj = setInterval(function () {
      
      
            getCode.innerText = "请" + second + "秒后再重试"
            if (second === 0) {
      
      
                getCode.innerText = "获取验证码"
                getCode.disabled = false
                clearInterval(intervalObj);
            }
            second--;
        }, 1000);
    }
    
    document.querySelector("#getCode").addEventListener('click', function () {
      
      
        const mail = document.querySelector("#mail")
        let xhr = new XMLHttpRequest();
        xhr.open("GET", "http://localhost:8080/getCode?targetEmail=" + mail.value, true);
        xhr.send();
        xhr.onreadystatechange = function () {
      
      
            if (xhr.readyState === 4) {
      
      
                alert(xhr.response);
                disabledButton()
            }
        }
    })

</script>
</body>
</html>

Je suppose que tu aimes

Origine blog.csdn.net/m0_66570338/article/details/128994951
conseillé
Classement