邮件注册(一)验证码发送

news2025/1/21 18:45:33

通过邮箱实现注册,用户请求验证码完成注册操作。

导入依赖:

<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-mail</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-amqp</artifactId>
		</dependency>

将验证码丢到消息队列中,再由监听器消费请求

配置完后进行测试:

//JavaMailSender是专门用于发送邮件的对象,自动配置类已经提供了Bean
	@Autowired
	JavaMailSender sender;

	@Test
	void contextLoads() {
		//SimpleMailMessage是一个比较简易的邮件封装,支持设置一些比较简单内容
		SimpleMailMessage message = new SimpleMailMessage();
		//设置邮件标题
		message.setSubject("【南京信息工程大学教务处】关于近期学校对您的处分决定");
		//设置邮件内容
		message.setText("赵国成同学您好,经监控和教务巡查发现,您近期存在旷课、迟到、早退、上课刷抖音行为," +
				"现已通知相关辅导员,请手写5000字书面检讨,并于2023年10月7号前交到辅导员办公室。");
		//设置邮件发送给谁,可以多个,这里就发给你的QQ邮箱
		message.setTo("786759086@qq.com");
		//邮件发送者,这里要与配置文件中的保持一致
		message.setFrom("18061946436@163.com");
		//OK,万事俱备只欠发送
		sender.send(message);
	}

在AccountService中增加方法:

public interface AccountService extends IService<Account> , UserDetailsService {
    Account findAccountByNameOrEmail(String text);
    //type区分用户是注册还是更改密码,从而显示不同的文本提示;通过用户ip地址限制请求的频率
    String RegisterEmailVerifyCode(String type, String email,String ip);
}

在服务代理中实现:

   @Override
    public String RegisterEmailVerifyCode(String type, String email, String ip) {
        Random random=new Random();
        //确保code为六位数
        int code=random.nextInt(899999)+100000;
        Map<String ,Object> data=Map.of("type",type,"email",email,"code",code);
        return type;
    }
    

配置消息队列专门处理邮箱,新建RabbitConfig类:

@Configuration
public class RabbitConfig {
 @Bean("emailQueue")
    public Queue emailQueue(){
        return (Queue) QueueBuilder.durable("mail").build();
    }
}

编写FlowUtils进行过滤:

@Component
public class FlowUtils {
    @Resource
    StringRedisTemplate template;
    public  boolean limitOnceCheck(String key,int blockTime){
        //正在冷却的状态
        if (Boolean.TRUE.equals(template.hasKey(key))){
return false;
        }
        else {
            //如果不在冷却时间内,可以发送邮件,发挥true,并更新冷却时间
            template.opsForValue().set(key,"",blockTime, TimeUnit.SECONDS);
            return true;
        }
    }
}

根据用户的ip进行过滤:

private boolean verifyLimit(String ip){
      String key= Const.VERIFY_EMAIL_LIMIT+ip;
      return flowUtils.limitOnceCheck(key,60);
}

RegisterEmailVerifyCode进行完善:

    @Override
    public String RegisterEmailVerifyCode(String type, String email, String ip) {
        if (this.verifyLimit(ip)) {
            Random random = new Random();
            //确保code为六位数
            int code = random.nextInt(899999) + 100000;
            Map<String, Object> data = Map.of("type", type, "email", email, "code", code);
            amqpTemplate.convertAndSend("mail", data);
            template.opsForValue()
                    .set(Const.VERIFY_EMAIL_DATA + email, String.valueOf(code), 3, TimeUnit.MINUTES);
            return null;
        }else {
            return "您的请求过于频繁,请稍后再试";
        }
    }

同一时间可能会被多次调用,此方法为线程不安全,因此需要上锁synchronized(ip.intern())

创建listener包,新建MailQueueListener类:

@Component
@RabbitListener(queues = "mail")
public class MailQueueListener {
    @Resource
    JavaMailSender sender;

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

    @RabbitHandler
    public void sendMailMessage(Map<String,Object> data){
        String email=(String) data.get("email");
        Integer code=(Integer) data.get("code");
        String type =(String) data.get("type");
        SimpleMailMessage message=switch (type){
            case "register"->
                createMessage("欢迎注册","验证码为:"+code+"有效时间为3分钟",email);
            case "reset"->
                createMessage("你的密码重置邮件","验证码为:"+code+"有效时间为3分钟",email);
            default -> null;
        };
        if (message==null)return;
        sender.send(message);
    }


    private SimpleMailMessage createMessage(String title,String content,String email){
        SimpleMailMessage message=new SimpleMailMessage();
        message.setSubject(title);
        message.setText(content);
        message.setTo(email);
        message.setFrom(username);
        return message;

    }

}

编写测试接口:

@RestController
@RequestMapping("/api/auth")
public class AuthorizeController {
    @Resource
    AccountService service;

    @GetMapping("/ask-code")
    public RestBean<Void> askVerifyCode(@RequestParam String email,
                                        @RequestParam String type,
                                        HttpServletRequest request) {
        String message = service.RegisterEmailVerifyCode(type, email, request.getRemoteAddr());
        return message== null ? RestBean.failure(400, message) : RestBean.success();
    }

}

注意确认在security配置中将测试地址放行。

当请求验证码时,首先进入对应的处理方法,调用service中的RegisterEmailVertifyCode方法,将目标邮箱和类型传入,通过httpServlet得到请求验证码的主机信息,在邮箱验证码方法中,通过random随机生成六位验证码,存入map中,通过amqpTemplate.convertAndSend(“mail”, data)将数据传入消息队列中,此处我们在rabbitconfig中建立了名为mail的emailqueue,接着利用redis数据库进行计时,将对应邮箱的验证码设置为3分钟过期,每次请求的ip地址设置冷却时间60秒,在每次请求前对ip地址进行过滤,最后设置rabbit监听器监听消息队列,一旦消息队列中有邮件数据,则进行读取并利用javaemail进行发送。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

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

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

相关文章

PACS系统 PACS系统源码一种用于存储、管理和传输医学影像数据的系统

医用软件中的影像归档与传输系统软件&#xff08;Picture Archiving and Communication System&#xff0c;简称PACS&#xff09;是一种用于存储、管理和传输医学影像数据的系统。其主要功能包括&#xff1a; 影像存储&#xff1a;PACS可以将医学影像数据以数字化的形式存储在服…

C语言之自定义类型_结构体篇(2)

目录 结构体传参 结构体实现位段&#xff08;位段的填充&可移植性&#xff09; 什么是位段 位段的大小计算 位段的内存分配 位段的跨平台问题 位段的应用 今天接着我们继续自定义类型结构体。&#x1f642;&#x1f642; 结构体传参 在我们初阶结构体我们学习过结…

Spring web security

儅使用spring的web security時&#xff0c;默認會轉向自帶的spring security example page。而不會轉向error page。 TODO: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId> &l…

城市、机场、服务区等场景下的智慧公厕建设诀窍揭秘

在如今繁忙的生活节奏中&#xff0c;人们对于公共服务设施的需求越来越高。而智慧公厕正是把传统公共厕所转变为智慧化的场所&#xff0c;得到了极大的欢迎。目前&#xff0c;各行各业均对公共厕所进行信息化、智慧化、数字化的升级&#xff0c;尤其是在机场、服务区和城市等场…

基于SSM的电子相册系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

6.MySql连接SqlYog

MySql连接SqlYog SqlYog和navicat均是数据可视化工具&#xff0c;熟悉其一即可 SqlYog下载安装 连接&#xff0c;密码和端口号一定要正确&#xff01;&#xff01;&#xff01; 2.保存到数据库 创建数据库&表 创建数据库 创建成功 创建表 点击保存 查看表数据的…

基于javaweb的智慧社区设计与实现

目录 前言 一、技术栈 二、系统功能介绍 客户信息管理 客户信息管理 社区信息管理 车位租买支付 前台车位信息 车位预定提交 问卷调查管理 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理…

【Spring篇】Bean的三种配置和实例化方法

&#x1f38a;专栏【Spring】 &#x1f354;喜欢的诗句&#xff1a;天行健&#xff0c;君子以自强不息。 &#x1f386;音乐分享【如愿】 &#x1f384;欢迎并且感谢大家指出小吉的问题&#x1f970; 文章目录 &#x1f33a;bean基本配置&#x1f33a;bean别名配置&#x1f33a…

RStudion | 基础使用教程(初学者详细) | 基本设置 | 快捷操作 | 脚本运行 | 画图

RStudion | 基础使用教程 | 基本设置 | 快捷操作 | 脚本运行 | 画图 一、RStudio界面布局二、RStudio基础设置2.1 general | 常规设置2.2 Code | 代码2.3 Console | 控制台2.4 Appearance | 外观2.5 Pane Layout | 排版布局2.6 Packages | R包2.7 R Markdown2.8 Python2.9 Swea…

反爬虫机制与反爬虫技术(一)

反爬虫机制与反爬虫技术一 1、网络爬虫的法律与道德问题2、反爬虫机制与反爬虫技术2.1、User-Agent伪装2.2、代理IP2.3、请求频率控制2.4、动态页面处理2.5、验证码识别3、反爬虫案例:豆瓣电影Top250爬取3.1、爬取目标3.2、库(模块)简介3.3、翻页分析3.4、发送请求3.5、提取…

【Python+requests+unittest+excel】实现接口自动化测试框架

一、框架结构&#xff1a; 工程目录 二、Case文件设计 三、基础包 base3.1 封装get/post请求&#xff08;runmethon.py&#xff09; 1 import requests2 import json3 class RunMethod:4 def post_main(self,url,data,headerNone):5 res None6 if header …

Javascript文件上传

什么是文件上传 文件上传包含两部分&#xff0c; 一部分是选择文件&#xff0c;包含所有相关的界面交互。一部分是网络传输&#xff0c;通过一个网络请求&#xff0c;将文件的数据携带过去&#xff0c;传递到服务器中&#xff0c;剩下的&#xff0c;在服务器中如何存储&#xf…

TL-ER3220G端口映射设置

1、打开IE浏览器或其它浏览器&#xff0c;在地址栏输入192.168.1.1登录路由器的Web管理界面&#xff1b; 2、打开后弹出密码输入框&#xff0c;输入路由器的用户名和密码&#xff0c;出厂默认值为admin/admin&#xff0c;成功登录后将看到路由器的系统状态信息&#xff1b; 3、…

2023 年 Web 安全最详细学习路线指南,从入门到入职(含书籍、工具包)【建议收藏】

第一个方向&#xff1a;安全研发 你可以把网络安全理解成电商行业、教育行业等其他行业一样&#xff0c;每个行业都有自己的软件研发&#xff0c;网络安全作为一个行业也不例外&#xff0c;不同的是这个行业的研发就是开发与网络安全业务相关的软件。 既然如此&#xff0c;那其…

MyBatisPlus(十三)逻辑查询:and / or

说明 逻辑查询&#xff0c;对应SQL语句中的多个查询条件进行逻辑组合&#xff0c;包括 and 和 or。 逻辑 “与” &#xff1a;and 默认情况下&#xff0c;多个查询条件&#xff0c;就是使用的逻辑与&#xff08;and&#xff09;连接&#xff0c;并不需要再使用 and() 函数。…

modelize.ai - 小记

文章目录 关于 关于 官网&#xff1a;https://www.beta.modelize.ai Modelize.ai是一个AI agents和teams的创作平台&#xff0c;通过结合多元的agents以及工作流的衔接&#xff0c;让AI agents之间高效协同&#xff0c;达到一键式完成复杂工作的效果。 公司的愿景是让AI打工人…

从零开始学习线性回归:理论、实践与PyTorch实现

文章目录 &#x1f966;介绍&#x1f966;基本知识&#x1f966;代码实现&#x1f966;完整代码&#x1f966;总结 &#x1f966;介绍 线性回归是统计学和机器学习中最简单而强大的算法之一&#xff0c;用于建模和预测连续性数值输出与输入特征之间的关系。本博客将深入探讨线性…

Texifier 专业打造,让你的LaTeX编辑更高效!

作为LaTeX用户&#xff0c;你一定知道寻找一款优秀的编辑工具是多么重要。而Texifier&#xff08;原Texpad&#xff09;就是你在Mac上寻找的完美解决方案&#xff01;它是一款专业的LaTeX编辑工具&#xff0c;为你带来高效、便捷的编辑体验。 Texifier拥有丰富的功能&#xff…

Linux网络编程系列之UDP协议编程

一、什么是UDP协议 UPD协议&#xff08;User Datagram Protocol&#xff0c;用户数据报协议&#xff09;是Internet协议族中的一个无连接协议&#xff0c;属于传输层&#xff0c;它不保证数据传输的可靠性或完整性&#xff0c;只是把应用程序发给网络层的数据封装成数据包进行传…

VL53L5CX驱动开发(1)----驱动TOF进行区域检测

VL53L5CX驱动开发----1.驱动TOF进行区域检测 闪烁定义视频教学样品申请源码下载主要特点硬件准备技术规格系统框图应用示意图区域映射生成STM32CUBEMX选择MCU 串口配置IIC配置X-CUBE-TOF1串口重定向代码配置Tera Term配置演示结果 闪烁定义 VL53L5CX是一款先进的飞行感应&…