SpringBoot集成邮箱验证码功能(注册/改密)

准备工作

开启SMTP服务

前往你的邮箱网站,以网易邮箱为例,打开网易邮箱地址,登录你的邮箱,进入邮箱管理后台界面。点击“设置”》》“POP3/SMTP/IMAP”后,点击开启SMTP服务即可。

技术实现


Spring Boot 发送邮件验证码的功能,主要用到了spring-boot-starter-mail工具包实现邮件的发送功能,利用junit-vintage-engine工具包实现了html邮件模板功能,利用easy-captcha工具包生成随机验证码 的功能!

引入依赖

     <!--引入mail依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
         <!--mail模板-->
         <dependency>
            <groupId>org.junit.vintage</groupId>
            <artifactId>junit-vintage-engine</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.hamcrest</groupId>
                    <artifactId>hamcrest-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
          <!--验证码-->
        <dependency>
            <groupId>com.github.whvcse</groupId>
            <artifactId>easy-captcha</artifactId>
            <version>1.6.2</version>
        </dependency>

相关配置

然后再spring的配置文件中,设置mail相关配置:

spring:
  mail:
    host: smtp.yeah.com
    username: 你的邮箱
    password: 邮箱授权码
    default-encoding: UTF-8
    protocol: smtp
    properties:
      mail:
        smtp:
           auth: true # 启用SMTP认证
           starttls:
              enabled: true # 启用SMTP认证
              required: true # 必须采用加密链接

代码实现

创建一个MailService类,实现邮件发送的功能,代码如下:

package com.ruoyi.framework.web.service;

import com.ruoyi.common.utils.DateUtils;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.UnsupportedEncodingException;
import java.util.Objects;


/**
 * 邮箱验证码
 *
 * @author lsyong
 */
@Component
public class MailService {

	private static final StringTemplateGroup templateGroup;

	private static final String SITE_NAME = "XXXXXXX";

	static{
		String classpath = Objects.requireNonNull(MailService.class.getClassLoader().getResource("")).getPath();
		templateGroup = new StringTemplateGroup("mailTemplates");
	}

	public static String IMG_BASE_URL;
	public static String ACTIVATE_CONTEXT="http:";
	public static String RESET_PWD_CONTEXT;

	@Value("${spring.mail.username}")
	private String username;
    @Resource
    private JavaMailSender mailSender;


    private void sendMail(String to, String subject, String body) {
    	MimeMessage mail = mailSender.createMimeMessage();
    	try {
    		MimeMessageHelper helper = new MimeMessageHelper(mail, true, "utf-8");
			helper.setFrom(new InternetAddress(MimeUtility.encodeText(SITE_NAME)+"<"+username+">").toString());
			helper.setTo(to);
			helper.setSubject(subject);
			helper.setText(body, true);
			helper.setSentDate(DateUtils.getNowDate());
			mailSender.send(mail);
		} catch (MessagingException|UnsupportedEncodingException e) {

		}
	}

    /**
     * 账号激活
     * @param to,key
     */
    public void sendAccountActivationEmail(String to, String key){
    	StringTemplate activation_temp = templateGroup.getInstanceOf("activation");
    	activation_temp.setAttribute("img_base_url", IMG_BASE_URL);
    	activation_temp.setAttribute("email", to);
    	activation_temp.setAttribute("href", ACTIVATE_CONTEXT+key+"?email="+to);
    	activation_temp.setAttribute("link", ACTIVATE_CONTEXT+key+"?email="+to);
    	sendMail(to, SITE_NAME+"账户激活", activation_temp.toString());
    }
    /**
     * 发送验证码
     * @param to,code
     */
	@Async
	public void sendEmailCode(String to, String code){
		StringTemplate activation_temp = templateGroup.getInstanceOf("verificationCode");
		activation_temp.setAttribute("img_base_url", IMG_BASE_URL);
		activation_temp.setAttribute("email", to);
		activation_temp.setAttribute("code", code);
		sendMail(to, SITE_NAME+"邮箱验证码", activation_temp.toString());
	}

    /**
     * 修改密码
     * @param to,key
     */
    public void sendResetPwdEmail(String to, String key){
    	StringTemplate activation_temp = templateGroup.getInstanceOf("resetpwd");
    	activation_temp.setAttribute("img_base_url", IMG_BASE_URL);
    	activation_temp.setAttribute("href", RESET_PWD_CONTEXT+"?key="+key+"&email="+to);
    	activation_temp.setAttribute("link", RESET_PWD_CONTEXT+"?key="+key+"&email="+to);
    	sendMail(to, SITE_NAME+"账户密码重置", activation_temp.toString());
    }
}

新建verificationCode.st 代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>XXXXXX邮箱验证码</title>
	<style type="text/css">
	body{
		font-family: '微软雅黑','Helvetica Neue',sans-serif;
	}
	.container{
		max-width: 600px;
		margin: 0 auto;
	}
	.segment{
		background: #fff;
    	border: 1px solid #e9e9e9;
    	border-radius: 3px;
    	padding: 20px;
	}
	.header{
		margin: 10px 0 30px 0;
		font-weight: 400;
    	font-size: 20px;
	}
	.logo{
	    margin: 0 auto;
	    text-align: center;
	    margin-bottom: 28px;
	}
	.logo img{
		width: 28px;
		height: auto;
	}
	</style>
</head>
<body>
	<div class="container">
		<div class="segment">
			<div class="logo">
				<img src="$img_base_url$logo_for_mail.png">
			</div>
			<div class="content">
				<div class="header">
					$email$
				</div>
				<p>欢迎加入XXXXXXX</p>
				<div>
					<p>您的验证码是:</p>
					<b>$code$</b>
				</div>
				<p>
					验证码有效时间为XX分钟,如果验证码失效,请重新点击发送验证码
				</p>
			</div>
		</div>
	</div>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/208143.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

跨越鸿沟-颠覆性产品营销指南笔记

跨越鸿沟-颠覆性产品营销指南笔记 一、发现鸿沟 一、技术采用生命周期 技术采用生命周期 如果采用一个新产品&#xff0c;我们就得改变一贯的行为模式&#xff0c;或者改变我们依赖的其他产品或服务&#xff0c;那么&#xff0c;我们对技术采用的态度就变得很重要&#xff0c…

入门单片机和嵌入式必须学模电数电吗?

入门单片机和嵌入式必须学模电数电吗&#xff1f; 关于这个话题答案&#xff0c;不能一概而论&#xff0c;主要与从事的具体工作内容有关。 嵌入式开发&#xff0c;好多人认为硬件和软件都需要学习&#xff0c;其实不然。 嵌入式领域涵盖的内容很广&#xff0c;比如嵌入式MCU、…

【编译警告】start value has mixed support, consider using flex-start instead

css规范问题&#xff0c;flex布局下&#xff0c;justify-content:start; 应该为&#xff1a;justify-content: flex-start

深入探索Maven:优雅构建Java项目的新方式(二)

Meven高级 1&#xff0c;属性1.1 属性1.1.1 问题分析1.1.2 解决步骤步骤1:父工程中定义属性步骤2:修改依赖的version 1.2 配置文件加载属性步骤1:父工程定义属性步骤2:jdbc.properties文件中引用属性步骤3:设置maven过滤文件范围步骤4:测试是否生效 1.3 版本管理 2&#xff0c;…

【Python表白系列】无限弹窗,满屏表白代码来啦(完整代码)

文章目录 满屏表白代码环境需求完整代码详细分析系列文章 满屏表白代码 环境需求 python3.11.4PyCharm Community Edition 2023.2.5pyinstaller6.2.0&#xff08;可选&#xff0c;这个库用于打包&#xff0c;使程序没有python环境也可以运行&#xff0c;如果想发给好朋友的话需…

什么是勒索软件

勒索软件 1. 定义2. 勒索软件的类型3. 勒索软件的工作方式4. 如何处置勒索软件 1. 定义 勒索软件又称勒索病毒&#xff0c;是一种特殊的恶意软件。勒索软件的特殊之处在于&#xff0c;它采用加密等技术手段限制受害者访问系统或系统内的数据&#xff08;如文档、邮件、数据库、…

基于YOLOv8深度学习的钢材表面缺陷检测系统【python源码+Pyqt5界面+数据集+训练代码】目标检测、深度学习实战

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【Skynet 入门实战练习】分布式 ID | 雪花算法 | 缓存设计 | LRU算法 | 数据库

文章目录 前言雪花算法LRU 算法缓存模块数据库测试逻辑 前言 本节实现了 分布式 ID 生成系统&#xff0c;采用雪花算法实现唯一 ID&#xff1b;实现缓存架构&#xff0c;采用 LRU &#xff08;最近最少使用&#xff09;算法。 雪花算法 分布式 ID 生成算法的有很多种&#x…

hadoop-3.3.5安装过程

准备资源三台虚拟机&#xff1a; 1&#xff09;准备3台服务器&#xff08;关闭防火墙、静态IP、主机名称&#xff09; 2&#xff09;安装JDK 3&#xff09;配置环境变量 4&#xff09;安装Hadoop 5&#xff09;配置环境变量 安装虚拟机&#xff08;略&#xff09;--1台即…

四、C语言数据类型和变量

目录 1. 数据类型介绍 1.1 字符型 1.2 整型 1.3 浮点型 1.4 布尔类型 1.5 各种数据类型的长度 1.5.1 sizeof 操作符 1.5.2 数据类型长度 2. signed 和 unsigned 3. 数据类型的取值范围 4. 变量 4.1 变量的创建 4.2 变量的分类 5. 算术操作符&#xff1a;、-、*、…

postman参数为D:\\audio\\test.mp3请求报错

报错信息 报错 java.lang.IllegalArgumentException: Invalid character found in the request target [/v1/audio/transcriptions?audioPathD:\\audio\\test.mp3 ]. The valid characters are defined in RFC 7230 and RFC 3986 解决方式 yml文件上放行指定字符 relaxed-pa…

【Docker】本地项目打包并发布到线上

部署python到docker 再把docker部署到服务器上 部署 Python 项目到 Docker 并将 Docker 容器部署到服务器通常需要执行以下步骤&#xff1a; 准备 Dockerfile&#xff1a; 在项目根目录创建一个名为 Dockerfile 的文件&#xff0c;该文件包含构建 Docker 镜像的指令。 # 设置…

Linux进程详解

Linux进程详解 1、进程概述1.1并行和并发1.2 PCB1.3 进程状态1.4 进程命令 2、进程创建2.1 函数2.2 fork()解析 3、父子进程3.1 进程执行位置3.2 循环创建子进程3.3 终端显示问题3.4 进程数数 4、execl和execlp4.1 execl()4.2 execlp()4.3 函数的使用 5、进程控制5.1 结束进程5…

nodejs的安装和验证

1.浏览器访问nodejs官网&#xff0c;根据操作系统选择对应版本的安装文件&#xff0c;如下图所示&#xff1a; 2.双击下载的安装文件&#xff0c;点击“Next”&#xff0c;如下图所示&#xff1a; 3.勾选“I accept the terms in the License Agreement”&#xff0c;然后点击“…

笔记----单纯剖分----1

笔记----单纯剖分 定义 线性组合仿射组合&#xff1a; 线性组合的系数为1凸组合&#xff1a; 仿射组合所有的系数都是正数 凸集 R^m 的 任意有限个点的凸组合仍在其中的子集仿射子空间 R^m 的 任意有限个点的仿射组合仍在其中的子集凸包 conv(A) A是R^m的一个子集 A的所有有限凸…

7.2 Windows驱动开发:内核注册并监控对象回调

在笔者上一篇文章《内核枚举进程与线程ObCall回调》简单介绍了如何枚举系统中已经存在的进程与线程回调&#xff0c;本章LyShark将通过对象回调实现对进程线程的句柄监控&#xff0c;在内核中提供了ObRegisterCallbacks回调&#xff0c;使用这个内核回调函数&#xff0c;可注册…

TZOJ 1405 An easy problem

翻译有些出错&#xff0c;但大概是那个意思 答案&#xff1a; #include <stdio.h> #include <ctype.h> //引用库函数isupper的头文件int main() {int T 0, i 0;scanf("%d", &T); //要输入的行数while (T--) //循环T次{char c;int y 0…

滴滴面试:什么是数据库事务?InnoDB一次事务的执行过程?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如滴滴、阿里、极兔、有赞、shein 希音、百度、网易的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 什么是数据库事务&#xff1f; 说说 InnoDB一次事务的执行过…

Matlab 点云线性指数计算(加权)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 思路其实很简单,即对每个邻近点集中的点,根据其到点集中心的距离进行加权处理(权重函数),之后再基于加权之后的点获取其协方差矩阵,最后再求取其相关的特征值,以此来获取该点的线性指数。相关公式如下所示:…

pytorch中Conv1d、Conv2d与Conv3d详解

1 卷积介绍 1.1 什么是卷积 卷积&#xff08;convolution&#xff09;&#xff0c;是一种运算&#xff0c;你可以类比于加&#xff0c;减&#xff0c;乘&#xff0c;除&#xff0c;矩阵的点乘与叉乘等等&#xff0c;它有自己的运算规则&#xff0c;卷积的符号是星号*。表达式…