邮件注册(一)验证码发送
通过邮箱实现注册,用户请求验证码完成注册操作。
导入依赖:
<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@AutowiredJavaMailSender sender;@Testvoid 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);
}
在服务代理中实现:
@Overridepublic 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 {@ResourceStringRedisTemplate 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进行完善:
@Overridepublic 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 {@ResourceJavaMailSender sender;@Value("${spring.mail.username}")String username;@RabbitHandlerpublic 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 {@ResourceAccountService 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进行发送。

相关文章:
邮件注册(一)验证码发送
通过邮箱实现注册,用户请求验证码完成注册操作。 导入依赖: <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><dependency><g…...
【网络安全---sql注入(2)】如何通过SQL注入getshell?如何通过SQL注入读取文件或者数据库数据?一篇文章告诉你过程和原理。
前言 本篇博客主要是通过piakchu靶场来讲解如何通过SQL注入漏洞来写入文件,读取文件。通过SQL输入来注入木马来getshell等,讲解了比较详细的过程; 如果想要学习SQL注入原理以及如何进行SQL注入,我也写了一篇详细的SQL注入方法及…...
正点原子嵌入式linux驱动开发——TF-A移植
经过了之前的学习,除了TF-A的详细启动流程仍待更新,TF-A的使用和其对应的大致启动流程已经进行过了学习。但是当我们实际做产品时,硬件平台肯定会和ST官方的有区别,比如DDR容量会改变,自己的硬件没有使用到官方EVK开发…...
GB28181学习(六)——实时视音频点播(数据传输部分)
GB28181系列文章: 总述:https://blog.csdn.net/www_dong/article/details/132515446 注册与注销:https://blog.csdn.net/www_dong/article/details/132654525 心跳保活:https://blog.csdn.net/www_dong/article/details/132796…...
JMeter接口自动化测试(数据驱动)
之前我们的用例数据都是配置在HTTP请求中,每次需要增加,修改用例都需要打开JMeter重新编辑,当用例越来越多的时候,用例维护起来就越来越麻烦,有没有好的方法来解决这种情况呢?我们可以将用例的数据存放在cs…...
数据结构:二叉树(超详解析)
目录 1.树概念及结构 1.1树的概念 1.2树的相关概念 1.3树的表示 1.3.1孩子兄弟表示法: 1.3.2双亲表示法:只存储双亲的下标或指针 两节点不在同一树上: 2.二叉树概念及结构 2.1.概念 2.2.特殊的二叉树: 2…...
【考研数学】高等数学第七模块 —— 曲线积分与曲面积分 | 4. 对坐标的曲面积分(第二类曲面积分)与场论初步
文章目录 二、曲面积分2.2 对坐标的曲面积分(第二类曲面积分)1. 问题产生 —— 流量2. 对坐标的曲面积分的定义(了解)3. 对坐标的曲面积分的性质4. 对坐标的曲面积分的计算法(1) 二重积分法(2&a…...
使用Thrift实现跨语言RPC调用
📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言Ὅ…...
【QT5-程序控制电源-RS232-SCPI协议-上位机-基础样例【1】】
【QT5-程序控制电源-RS232-SCPI协议-上位机-基础样例【1】】 1、前言2、实验环境3、自我总结1、基础了解仪器控制-熟悉仪器2、连接SCPI协议3、选择控制方式-程控方式-RS2324、代码编写 4、熟悉协议-SCPI协议5、测试实验-测试指令(1)硬件连接(…...
leetcode 1049. 最后一块石头的重量 II、494. 目标和、474. 一和零
1049. 最后一块石头的重量 II 有一堆石头,用整数数组 stones 表示。其中 stones[i] 表示第 i 块石头的重量。 每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x < y。那么粉碎的可能结果…...
Error string: Could not load library
启动Rivz时,报错: Error string: Could not load library (Poco exception libg2o_csparse_extension.so.0.1: cannot open shared object file: No such file or directory) [ERROR] [1696572310.529059051]: Failed to load nodelet [/radar_graph_s…...
pom.xml里的标签
pom.xml 是 Maven 项目的配置文件,其中包含了各种配置信息和依赖管理。下面是一些常见的 pom.xml 中的标签和其作用的简要说明: <project>:根标签,定义了整个项目的基本信息和结构。 <groupId>:指定项目所…...
微服务部署的正确策略
微服务部署挑战 单体应用程序的部署意味着您运行单个(通常是大型应用程序)的多个相同副本。这主要是通过配置 N 个服务器(无论是物理服务器还是虚拟服务器)并在每台服务器上运行应用程序的 M 个实例来完成。虽然这看起来非常简单…...
C#中的数组探究与学习
目录 C#中的数组一般分为:一.数组定义:为什么要使用数组?什么是数组?C#一维数组for和foreach的区别C#多维数组C#锯齿数组初始化的意义:适用场景:C#中的数组一般分为: ①.一维数组。 ②.多维数组,也叫矩形数组。 ③.锯齿数组,也叫交错数组。 一.数组定义: 数组…...
计算机网络八股
1、请你说说TCP和UDP的区别 TCP提供面向连接的可靠传输,UDP提供面向无连接的不可靠传输。UDP在很多实时性要求高的场景有很好的表现,而TCP在要求数据准确、对速度没有硬件要求的场景有很好的表现。TCP和UDP都是传输层协议,都是为应用层程序服…...
Waves 14混音特效插件合集mac/win
Waves14是一款音频处理软件,主要用于音频编辑、混音和母带处理。该软件提供了各种插件,包括EQ、压缩、混响、延迟、失真等,以及一些专业的音频处理工具,如L2限幅器、Linear Phase EQ和多频道扬声器管理。 Mac软件下载:…...
Python python-docx 使用教程
openpyxl是Python下的Word库,它能够很容易的对Word文档进行读取 安装方法:pip install python-docx国内镜像安装:pip install -i https://mirrors.aliyun.com/pypi/simple/ python-docx(推荐,安装更快)中文…...
Mac上protobuf环境构建-java
参考文献 getting-started 官网pb java介绍 maven protobuf插件 简单入门1 简单入门2 1. protoc编译器下载安装 https://github.com/protocolbuffers/protobuf/releases?page10 放入.zshrc中配置环境变量 ~/IdeaProjects/test2/ protoc --version libprotoc 3.12.1 …...
CocosCreator3.8研究笔记(二十二)CocosCreator 动画系统-动画剪辑和动画组件介绍
国庆假期,闲着没事,在家研究技术~ 大家都知道在Cocos Creator3.x 的版本的动画编辑器中,可以实现不用写一行代码就能实现各种动态效果。 Cocos Creator动画编辑器中主要实现关键帧动画,不仅支持位移、旋转、缩放、帧动画ÿ…...
信看课堂-厘米GNSS定位
我们常常说GPS 定位,不过定位远不止GPS定位,通过本节课程,我们将会了解到,原来GPS只是定位的一种: GNSS概述 不同的GNSS系统使用不同的频段来传输导航信号。以下是一些主要的GNSS系统及其相应的频段,用表…...
Fast-GitHub:3个技巧让国内开发者告别GitHub龟速时代
Fast-GitHub:3个技巧让国内开发者告别GitHub龟速时代 【免费下载链接】Fast-GitHub 国内Github下载很慢,用上了这个插件后,下载速度嗖嗖嗖的~! 项目地址: https://gitcode.com/gh_mirrors/fa/Fast-GitHub 你是否曾经因为Gi…...
嵌入式老C代码别重写!IAR项目混编C/C++的保姆级指南(extern “C“详解)
嵌入式老C代码别重写!IAR项目混编C/C的保姆级指南(extern "C"详解) 当你在IAR Embedded Workbench中启动一个新项目,面对那些历经千锤百炼的C语言驱动和BSP代码,是否曾为"推倒重来还是继续维护"而…...
3分钟快速搞定Windows苹果设备驱动安装:Apple-Mobile-Drivers-Installer终极指南
3分钟快速搞定Windows苹果设备驱动安装:Apple-Mobile-Drivers-Installer终极指南 【免费下载链接】Apple-Mobile-Drivers-Installer Powershell script to easily install Apple USB and Mobile Device Ethernet (USB Tethering) drivers on Windows! 项目地址: h…...
如何快速构建Python量化分析系统:5步掌握通达信数据接口
如何快速构建Python量化分析系统:5步掌握通达信数据接口 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx MOOTDX是一个基于Python的高效通达信数据接口封装,专为量化投资和数…...
Cursor编辑器集成OpenAPI Agent:让AI编程助手具备真实API调用能力
1. 项目概述:当你的代码编辑器学会“思考”最近在开发者社区里,一个名为neordinary/cursor-openapi-agent的项目引起了我的注意。乍一看,这名字有点长,但拆解一下就能明白它的野心:cursor是那款风头正劲的、集成了AI能…...
医疗软件开发框架Framewright:HIPAA合规与FHIR集成实践
1. 项目概述:一个为医疗软件量身定制的开发框架 如果你在医疗软件行业摸爬滚打过几年,一定会对开发过程中的那些“特殊要求”深有体会。这不仅仅是写个增删改查的CRUD应用那么简单,你得时刻绷紧神经,处理HIPAA合规、处理复杂的医学…...
若依框架实战:参数验证异常处理(手机号码格式验证案例)
一、前言在后端开发中,参数校验是保证接口健壮性的第一道防线。若依(Ruoyi)框架作为主流的 Java 后台管理系统框架,内置了完善的参数验证与全局异常处理机制。本文将以用户管理模块的手机号码格式验证为例,从触发验证、…...
ADI GitHub工程编译指南:以ADRV9009/ZC706为例,搞懂Tcl脚本工程的结构与自动化构建
ADI GitHub工程编译指南:深入解析Tcl脚本工程与自动化构建体系 当你在GitHub上打开Analog Devices的HDL仓库时,可能会被密密麻麻的Tcl脚本和Makefile文件搞得一头雾水。这种以脚本驱动的硬件项目组织方式,正逐渐成为开源硬件领域的标准实践。…...
TS3380,TS3480,ts8220,ts6150,ts5380,G1810,G2000,G2010,G2800,G2810报错5B00,P07,E08,1700,5b04废墨垫清零,亲测有用。
下载:点这里下载 备用下载:https://pan.baidu.com/s/1WrPFvdV8sq-qI3_NgO2EvA?pwd0000 常见型号如下: G系列 G1000、G1100、G1200、G1400、G1500、G1800、G1900、G1010、G1110、G1120、G1410、G1420、G1411、G1510、G1520、G1810、G1820、…...
基于Qt与STM32的跨平台遥控小车调试助手设计与实现
1. 项目背景与需求分析 遥控小车作为嵌入式开发的经典项目,调试环节往往是最耗时的部分。传统调试方式需要反复修改下位机代码、烧录固件、观察串口打印数据,整个过程效率低下。我在实际项目中就遇到过这样的困扰:每次调整PID参数都要重新编译…...
