SpringBoot实现邮箱验证

news2024/12/25 9:32:53

目录

1、开启邮箱IMAP/SMTP服务,获取授权码

2、相关代码

        1、使用配置Redis(用于存储验证码,具有时效性)

        2、邮箱依赖和hutool(用于随机生成验证码)

        3、配置Redis和邮箱信息

        4、开启Redis服务

        5、编写发送邮箱验证码

        6、邮箱登录验证功能

3、测试


1、开启邮箱IMAP/SMTP服务,获取授权码

        1、登录邮箱(以qq邮箱为例),点击邮箱右上角邮箱-设置-常规-第三方服务,会有如下选项

        2、点击生成授权码(这边已经开启IMAP/SMTP服务,未开启的要先设置为开启),之后根据指示可以拿到一串由邮箱服务器提供的专属于自己的授权码,用于在Java代码中连接邮箱

2、相关代码

        1、使用配置Redis(用于存储验证码,具有时效性)
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        2、邮箱依赖和hutool(用于随机生成验证码)
        <!-- 邮箱验证码依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <!-- 一个很强大的工具库 -->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.19</version>
        </dependency>
        3、配置Redis和邮箱信息
  redis:
    host: localhost
    port: 6379

  mail:
    host: smtp.qq.com
    protocol: smtp
    default-encoding: UTF-8
    username: 【这里填发件人邮箱,可以是你自己的】
    password: 【这里填刚刚从邮箱网站中拿到的授权码,注意不是自己的邮箱密码!!】



    nickname: 【发件人自命名】
    properties:
      mail.smtp.auth: true #启用SMTP服务器的身份验证,这是为了确保只有合法用户可以发送邮件。
      mail.smtp.starttls.enable: #启用TLS加密,这是为了确保邮件传输的安全性。
      mail.smtp.starttls.required: true #要求使用TLS加密,如果连接不是通过TLS加密传输,则连接将失败。
        4、开启Redis服务

        这里以windows作为举例:

        5、编写发送邮箱验证码
import cn.hutool.core.util.RandomUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/email")
public class EmailController {

    @Autowired
    private JavaMailSender javaMailSender;

    @Autowired
    private RedisTemplate redisTemplate;

    @Value("${spring.mail.username}")
    private String sender;

    @Value("${spring.mail.nickname}")
    private String nickname;

    @GetMapping("/code")
    public String getCode(@RequestParam("email") String email){

        // 创建一个邮件
        SimpleMailMessage message = new SimpleMailMessage();

        // 设置发件人
        message.setFrom(nickname+'<'+sender+'>');

        // 设置收件人
        message.setTo(email);

        // 设置邮件主题
        message.setSubject("欢迎访问"+nickname);

        //生成六位随机数
        String code = RandomUtil.randomNumbers(6);

        //将验证码存入redis,有效期为5分钟
        redisTemplate.opsForValue().set("email_code_"+email, code, 300000, TimeUnit.MILLISECONDS);

        String content = "【验证码】您的验证码为:" + code + " 。 验证码五分钟内有效,逾期作废。\n\n\n" +
                "------------------------------\n\n\n" ;

        message.setText(content);

        // 发送邮件
        javaMailSender.send(message);

        return "发送成功";


    }

}
        6、邮箱登录验证功能
@RestController
@RequestMapping("/user")
public class UserController {



       @Resource
       private RedisTemplate redisTemplate;


       // 通过邮箱验证登录
       @PostMapping("/loginByEmail")
        public ResponseBean loginByEmail(@RequestParam(value = "code") String code) {

          String email = "【这里写你已经收到验证码的邮箱】";

          String emailKey  = "email_code_"+email;

          String storedToken = (String) redisTemplate.opsForValue().get(emailKey);

          if(code.equals(storedToken)){

              return ResponseBean.success("验证成功",null);
          }else {

              return ResponseBean.error("验证失败");
          }

       }

}

3、测试

                                                 成功接收到来自发送方的验证码

再进行邮箱登录测试

    

        检查Redis服务器存储情况:

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

广东智慧公厕管理系统哪家好@光明源

随着城市发展和人民生活水平的提高&#xff0c;智慧公厕作为城市公共卫生设施的重要组成部分&#xff0c;受到了越来越多城市管理者的重视。在广东&#xff0c;智慧公厕管理系统的选择成为了一个备受关注的话题。那么&#xff0c;在广东&#xff0c;到底哪家智慧公厕管理系统比…

某程旅行安全工程师一面

一、自我介绍 阿吧阿吧&#xff0c;不多说了 二、两段实习经历&#xff0c;看你在南京中孚数据安全部做实习生&#xff0c;你能大概讲一下做什么的吗 当时做的是一个隐写溯源项目&#xff0c;是我们实验室跟南京中孚那边共同合作的。主要是针对电子文档信息泄露&#xff0c;…

牛市来临,模块化赛道可能会出现下个以太坊?

市场专家普遍预测&#xff0c;2024年将成为加密货币市场迎来新一轮牛市的关键时刻。研究人员将下一次比特币&#xff08;BTC&#xff09;减半以及2024年现货BTC ETF&#xff08;交易所交易基金&#xff09;的可能性视为推动下一次牛市的潜在因素。这一牛市的可能爆发有望吸引大…

C# Web应用调用EXE文件的一些实践

目录 需求 范例运行环境 可执行文件的设计 调用可执行文件方法 RunExecuteFile RunShellExecuteFile 方法的区别 WEB调用举例 小结 需求 最近同事使用Python开发了一款智能文字转语音的程序&#xff0c;经讨论部署在WINDOWS环境服务器下&#xff0c;因此需要生成目标…

C语言函数实现冒泡排序

前言 今天我们来看看怎么使用函数的方式实现冒泡排序吧&#xff0c;我们以一个数组为例arr[] {9,8,7,6,5,4,3,2,1,0},我们将这个数组通过冒泡排序的方式让他变为升序吧。 代码实现 #include<stdio.h> void bubble_sort(int arr[], int sz) {int i 0;for (i 0;i < s…

如何使用GraphQL和Apollo构建一个宝可梦应用

宝可梦是一个由视频游戏、动画系列与电影、交换卡牌游戏以及其他相关媒体组成的日本媒体特许经营权。 在本文中&#xff0c;我们将使用一个宝可梦GraphQL API&#xff0c;该API提供有关不同宝可梦的数据。 我们将使用Apollo和GraphQL来处理数据获取&#xff0c;以及React来构…

数据库之DCL操作(用户、访问权限。)

DCL英文全称是Data control language(数据控制语言)&#xff0c;用来管理数据库用户、控制数据库的访问权限。 1.管理用户 1.1查询用户 select * from mysql.user; 其中 Host代表当前用户访问的主机&#xff0c;如果为localhost&#xff0c;仅代表只能够在当前本机访问&…

git上传到本地仓库

摘要&#xff1a;本地初始化init仓库&#xff0c;进行pull和push&#xff1b;好处是便于利用存储设备进行git备份 git init --bare test.git 随便到一个空的目录下git clone 然后使用git上传 把git仓库删除之后再clone一次验证一下是否上传成功&#xff1a; 如果在ubantu上面没…

嵌入式面向对象学习 RT-Thread I/O 设备管理框架 设备驱动层 案例测试

嵌入式面向对象 RT-Thread I/O 设备管理框架 设备驱动层 注&#xff1a;本文介绍性内容转载于《RT-Thread记录&#xff08;十、全面认识 RT-Thread I/O 设备模型&#xff09;》 注&#xff1a; 本次使用的开发板 &#xff1a; ​ 兆易创新GD32F407VET6开发板 ​ 雅特力科技…

c++的学习之路:7、类和对象(3)

目录 一、初始化列表 二、static成员 三、友元 四、内部类 五、匿名对象 六、类和对象的思维导图 一、初始化列表 初始化列表&#xff1a;以一个冒号开始&#xff0c;接着是一个以逗号分隔的数据成员列表&#xff0c;每个"成员变量"后面跟一个放在括号中的初始…

求m和n的最大公约数(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>int main() {//初始化变量值&#xff1b;int remainder 1;int m 0;int n 0;int middle 0;//提示用户&#xff1b;printf("请输入整数m和n的值&#xff…

辅助PC端教程

使用谷歌浏览器打开京东,并登录好账号进入到 https://home.jd.com/ ,在根据下面操作 更多工具 - 开发者工具,会有一个窗口打开,选择network,点击XHR

撸代码时,有哪些习惯一定要坚持?

我从2011年开始做单片机开发&#xff0c;一直保持以下撸代码的习惯。 1.做好代码版本管理 有些人&#xff0c;喜欢一个程序干到底&#xff0c;直到实现全部的产品功能&#xff0c;我以前做51单片机的项目就是这样。 如果功能比较多的产品&#xff0c;我不建议这样做&#xff0…

编译原理实验2(自上而下语法分析)

一、实验目的 给出 PL/0 文法规范&#xff0c;要求编写 PL/0 语言的语法分析程序。通过设计、编制、调试一个典型的自上而下语法分析程序&#xff0c;实现对词法分析程序所提供的单词序列进行语法检查和结构分析&#xff0c;进一步掌握常用的语法分析方法。选择有代表性的语法…

一款轻量、干净的 Vue 后台管理框架

开始之前 在开始介绍之前我想谈谈为什么要自己做一个后台管理&#xff0c;我知道很多人都用一些开源的后台管理项目&#xff0c;这些老前辈有很多亮点值得学习&#xff0c;但是存在的一些问题同样不可忽视&#xff0c;我认为很多开发者会被困扰(仅代表个人观点) 技术栈老旧不升…

面试(03)————多线程和线程池

一、多线程 1、什么是线程?线程和进程的区别? 2、创建线程有几种方式 &#xff1f; 3、Runnable 和 Callable 的区别&#xff1f; 4、如何启动一个新线程、调用 start 和 run 方法的区别&#xff1f; 5、线程有哪几种状态以及各种状态之间的转换&#xff1f; 6、线程…

Docker容器与虚拟化技术:OpenEuler 部署 ES 与 Kibana

目录 一、实验 1.环境 2.OpenEuler 部署 ES (EalasticSearch) 3.OpenEuler 部署 Kibana 4.部署 Elasticvue插件 5.使用cpolar内网穿透 6.使用Elasticvue 一、实验 1.环境 &#xff08;1&#xff09;主机 表1 主机 系统架构版本IP备注LinuxopenEuler22.03 LTS SP2 1…

flex布局align-items和align-content、justfiy-content的区别

justfiy-content&#xff1a;定义主轴的对齐方式align-items&#xff1a;定义交叉轴的对齐方式align-content&#xff1a;将flex子项作为一个整体起作用 只在两种情况下有效果&#xff1a; ①子项多行且flex容器高度固定 ②子项单行&#xff0c;flex容器高度固定且设置了fle…

Mac安装配置Appium

一、安装 nodejs 与 npm 安装方式与 windows 类似 &#xff0c;官网下载对应的 mac 版本的安装包&#xff0c;双击即可安装&#xff0c;无须配置环境变量。官方下载地址&#xff1a;https://nodejs.org/en/download/ 二、安装 appium Appium 分为两个版本&#xff0c;一个是…

HarmonyOS实战开发-屏幕属性(仅对系统应用开放)

介绍 本示例主要展示了屏幕管理相关的功能&#xff0c;使用ohos.display、ohos.screen接口&#xff0c;ohos.display接口提供获取默认display对象、获取所有display对象&#xff0c;开启监听、关闭监听功能&#xff1b;ohos.screen接口提供创建虚拟屏幕、销毁虚拟屏幕、扩展屏…