【实现方案】Springboot结合HttpSession实现邮箱验证码验证用户

本文介绍如何使用Spring框架的JavaMailSender组件发送带有验证码的邮件,包括配置邮件发送、使用Thymeleaf模板引擎生成邮件内容,以及在服务器端通过HttpSession保存和验证验证码的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前置说明

本文使用 spring 框架中自带的 JavaMailSender 发送邮件,使用HttpSession 在服务器端保存会话信息,储存生成的验证码,以便客户端输入验证码进行验证。

邮箱验证码验证

众所周知,邮件可以包含很多种类的内容。在本文中,邮件内容分为:纯文本、HTML代码(Thymeleaf模板)、附件、图片。看完内容类型可以得知,其实内容为 HTML 代码或附件是最好用的。

验证流程:
  1. 客户端发送获取验证码请求
  2. 服务器端通过 VerifyCodeService 生成验证码,并将验证码放入 session 中
  3. 服务器将验证码通过 MailService 发送到用户邮箱
  4. 用户输入验证码,通过验证
代码示例

1、maven依赖
注意:starter-mail 要是 2.1.3.RELEASE 以下的,这样可以使用 JavaMailHelper,2.1.6.RELEASE 及以上不清楚调用什么api可以发邮件,感兴趣的同学可以查一下官方文档~

		<!--        邮件内容使用的模板引擎-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--        注意:2.1.6没有JavaMailSender-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
            <version>2.1.3.RELEASE</version>
        </dependency>

2、application.properties配置
在此处配置发送邮件以及使用模板的配置。

## mail config ##
#163的SMTP服务器
spring.mail.host=smtp.163.com
#发件邮箱的账号和密码
spring.mail.username=xxx@163.com
spring.mail.password=xxx
spring.mail.default-encoding=utf-8

## thymeleaf config##
spring.thymeleaf.mode=HTML5
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.cache=false

## default config ##
mail.from.addr=xxx@163.com

3、MailService
提供发送不同类型内容邮件的服务。

/**
 * @author amber
 */
public interface MailService {

    /**
     * 发送普通文本邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 内容
     */
    void sendSimpleMail(String to, String subject, String content);

    /**
     * 发送HTML邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 内容(可以包含<html>等标签)
     */
    void sendHtmlMail(String to, String subject, String content);

    /**
     * 发送带附件的邮件
     *
     * @param to       收件人
     * @param subject  主题
     * @param content  内容
     * @param filePath 附件路径
     */
    void sendAttachmentMail(String to, String subject, String content, String filePath);

    /**
     * 发送带图片的邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 文本
     * @param rscPath 图片路径
     * @param rscId   图片ID,用于在<img>标签中使用,从而显示图片
     */
    void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);

}

4、MailServiceImpl
MailService 服务实现。

import com.amber.verifycode.service.MailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;


/**
 * @author amber
 */
@Service
public class MailServiceImpl implements MailService {

    @Value("${mail.from.addr}")
    private String from;

    @Autowired
    JavaMailSender javaMailSender;

    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        //收信人
        message.setTo(to);
        //主题
        message.setSubject(subject);
        //内容
        message.setText(content);
        //发信人
        message.setFrom(from);

        try {
            javaMailSender.send(message);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void sendHtmlMail(String to, String subject, String content) {
        try {
            MimeMessage message = javaMailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            //true代表支持html
            helper.setText(content, true);
            javaMailSender.send(message);
        } catch (MessagingException e){

        }
    }

    @Override
    public void sendAttachmentMail(String to, String subject, String content, String filePath) {
        MimeMessage message = javaMailSender.createMimeMessage();

        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(message, true);
            //true代表支持多组件,如附件,图片等
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            FileSystemResource file = new FileSystemResource(new File(filePath));
            String fileName = file.getFilename();
            //添加附件,可多次调用该方法添加多个附件
            helper.addAttachment(fileName, file);
            javaMailSender.send(message);
        } catch (MessagingException e) {

        }
    }

	@Override
    public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) {
        MimeMessage message = javaMailSender.createMimeMessage();

        MimeMessageHelper helper;
        try {
            helper = new MimeMessageHelper(message, true);
            helper.setFrom(from);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);
            FileSystemResource res = new FileSystemResource(new File(rscPath));
            //重复使用添加多个图片
            helper.addInline(rscId, res);
            javaMailSender.send(message);
        } catch (MessagingException e) {
        }
    }
}

5、VerifyCodeService
生成以及发送验证码的服务。

/**
 * @author amber
 */

public interface VerifyCodeService {

    /**
     * 随机生成6位验证码:大写英文字符 + 数字
     * @return 验证码
     */
    String getEmailCode();

    /**
     * 随机生成6位验证码,全部为数字组成。
     * @return 验证码
     */
    String getPhoneCode();

    /**
     * 发送验证码至相应邮箱
     * @param to 收件人
     * @param subject 主体
     * @param verifyCode 内容
     */
    void sendCode2Email(String to, String subject, String verifyCode);
}

6、VerifyCodeServiceImpl
VerifyCode服务的实现。

import com.amber.verifycode.service.MailService;
import com.amber.verifycode.service.VerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

/**
 * @author amber
 */

@Service
public class VerifyCodeServiceImpl implements VerifyCodeService {

    @Autowired
    MailService mailService;

    @Autowired
    TemplateEngine templateEngine;

    @Override
    public String getEmailCode() {
        StringBuilder code = new StringBuilder();
        int dir = 0;
        for (int i = 0; i < 8; i++) {
            dir = (Math.random() > 0.5) ? 1 : 0;
            if (dir == 1) {
                //拼数字
                code.append((int) (Math.random() * 9));
            } else {
                //拼字母
                code.append(getRandomCapitalLetter());
            }
        }
        return code.toString();
    }

    @Override
    public String getPhoneCode() {
        StringBuilder code = new StringBuilder();
        for (int i = 0; i < 6; i++) {
            code.append((int) (Math.random() * 9));
        }
        return code.toString();
    }

    @Override
    public void sendCode2Email(String to, String subject, String verifyCode) {
    	//把验证码放到thymeleaf模板中
        Context context = new Context();
        context.setVariable("verifyCode", verifyCode);
        String emailContent = templateEngine.process("emailTemplate", context);
        //发送邮件
        mailService.sendHtmlMail(to, subject, emailContent);
    }

	//随机生成大写英文字母
    private char getRandomCapitalLetter() {
        int i = (int) (Math.random() * 25);
        //大写字母的ASCII值为65-90
        int j = i + 65;
        char letter = (char) j;
        return letter;
    }
}

7、VerifyCodeController
这里 controller 只提供验证作用,实际业务场景可根据 HttpSession 提供的api进行设置。

import com.amber.verifycode.service.MailService;
import com.amber.verifycode.service.VerifyCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author amber
 */
@Controller
@RequestMapping("/verifyCode")
public class VerifyCodeController {

    @Autowired
    MailService mailService;
    @Autowired
    VerifyCodeService verifyCodeService;

    @RequestMapping("/mail")
    @ResponseBody
    public Object sendVerifyCode(HttpServletRequest request, HttpServletResponse response) {

        String verifyCode = verifyCodeService.getEmailCode();
        verifyCodeService.sendCode2Email("xx@qq.com", "SimpleTest", verifyCode);

        HttpSession session = request.getSession(false);
        if (session == null) {
            //创建session,并拿到JSESSIONID
            session = request.getSession();
        }
        //设置session有效时间,默认是1800s
        session.setMaxInactiveInterval(900);
        //将验证码放入session中
        session.setAttribute("verifyCode", verifyCode);
        return "success!";
    }

    @RequestMapping("/verify")
    @ResponseBody
    public Object verify(String inputCode, HttpServletRequest request){
        HttpSession session = request.getSession();
        String verifyCode = (String) session.getAttribute("verifyCode");

        if (inputCode.equals(verifyCode)){
            //主动使session无效
            session.invalidate();
            return true;
        }
        return false;
    }
}

8、emailTemplate.html
邮件内容模板。

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    您好,本次验证的验证码为:[[${verifyCode}]]
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值