SpringBoot集成邮件服务进行校验

时间:2024-01-21 07:24:33

一、前言

在我们进行注册、登录等操作的时候,为了保证用户信息的安全性,我们经常会需要接收短信验证码等场景,虽然它的安全系数较高,但是由于需要付费使用,所以我们也可以使用邮箱服务接收验证码来实现安全校验,提升系统安全系数。

二、环境准备

以QQ邮箱为例,我们需要在邮箱中开启SMTP服务获取授权码。

SpringBoot集成邮件服务进行校验_SpringBoot

SpringBoot集成邮件服务进行校验_邮件_02

点击生成授权码。

SpringBoot集成邮件服务进行校验_邮件_03

SpringBoot集成邮件服务进行校验_验证码_04

三、SpringBoot集成

1.引入依赖

<!--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>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2.创建邮件发送的控制层

package com.example.nettyserverdemo.controller;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;

/**
 * @author qx
 * @date 2023/12/29
 * @des 邮件发送控制层
 */
@RestController
public class EmailController {

    @GetMapping("/getCode")
    public void sendMail(@RequestParam("targetEmail") String targetEmail) throws EmailException {
        // 生成6位随机验证码
        String code = String.valueOf(new Random().nextInt(899999) + 100000);
        SimpleEmail email = new SimpleEmail();
        // 设置发送邮件的服务器
        email.setHostName("smtp.qq.com");
        String myEmail = "136xxxxxx@qq.com";
        email.setAuthentication(myEmail, "xxxxxxxxx");
        // 发送者邮箱
        email.setFrom(myEmail);
        // 用于接收验证码的邮箱
        email.addTo(targetEmail);
        // 邮件的主题
        email.setSubject("注册验证码");
        // 邮件的内容
        email.setMsg("您的验证码为:" + code + "(一分钟有效)");
        // 发送邮件
        email.send();
    }
}

启动程序,我们先简单测试一下看看邮箱是否接收到验证码。

SpringBoot集成邮件服务进行校验_验证码_05

我们在接收的邮箱中发现确实收到了验证码的邮件。

SpringBoot集成邮件服务进行校验_验证码_06

3.优化

上面我们提到了验证码在一分钟内有效,那么我们就需要设置在这个时间内,我们不能频繁去请求邮箱获取验证码。我们就需要使用Redis来优化我们的代码。

package com.example.nettyserverdemo.controller;

import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.SimpleEmail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.TimeUnit;

/**
 * @author qx
 * @date 2023/12/29
 * @des 邮件发送控制层
 */
@RestController
public class EmailController {

    @Autowired
    private StringRedisTemplate redisTemplate;


    @GetMapping("/getCode")
    public String sendMail(@RequestParam("targetEmail") String targetEmail) throws EmailException {
        // 获取redis中指定邮箱为key的数据
        String redisCode = redisTemplate.opsForValue().get(targetEmail);
        if (redisCode == null) {
            // 生成6位随机验证码
            String code = String.valueOf(new Random().nextInt(899999) + 100000);
            // 验证码保存到redis中 接收邮箱为key,验证码为值 有效期为1分钟
            redisTemplate.opsForValue().set(targetEmail, code, 1, TimeUnit.MINUTES);
            SimpleEmail email = new SimpleEmail();
            // 设置发送邮件的服务器
            email.setHostName("smtp.qq.com");
            String myEmail = "13xxxxxx3@qq.com";
            email.setAuthentication(myEmail, "xxxxxxx");
            // 发送者邮箱
            email.setFrom(myEmail);
            // 用于接收验证码的邮箱
            email.addTo(targetEmail);
            // 邮件的主题
            email.setSubject("注册验证码");
            // 邮件的内容
            email.setMsg("您的验证码为:" + code + "(一分钟有效)");
            // 发送邮件
            email.send();
            return "验证码发送成功";
        }
        return "请勿重复发送验证码";
    }
}

我们重新启动程序继续进行测试。我们短时间内频繁请求获取邮箱验证码会提示错误。

SpringBoot集成邮件服务进行校验_邮件_07

1分钟后我们继续测试,由于redis中的数据过期了,所以又重新获取到了验证码并发送到指定的邮箱。

SpringBoot集成邮件服务进行校验_邮件_08

SpringBoot集成邮件服务进行校验_邮件_09