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

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

导入依赖:

<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进行发送。

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

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

消息队列技术选型:这 7 种消息场景一定要考虑!

大家好&#xff0c;我是君哥。 我们在做消息队列的技术选型时&#xff0c;往往会结合业务场景进行考虑。今天来聊一聊消息队列可能会用到的 7 种消息场景。 1 普通消息 消息队列最基础的功能就是生产者发送消息、Broker 保存消息&#xff0c;消费者来消费消息&#xff0c;以…

Stm32_标准库_6_八种输入出模式

上拉输入与下拉输入 上拉输入&#xff1a;电平默认为高电平&#xff0c;只有当外部输入为低电平时&#xff0c;此IO口电平才会被拉低&#xff0c;经过触发器&#xff0c;再到寄存器&#xff0c;最后传入CPU GPIO_Mode_IPU&#xff1b;下拉输入&#xff1a;电平默认为低电平&am…

机器学习小知识--面试得一塌糊涂

机器学习中需要归一化的算法有SVM, 逻辑回归&#xff0c;神经网络&#xff0c;KNN, 线性回归&#xff0c;而树形结构的不需要归一化&#xff0c;因为它们不关心变量的值&#xff0c;而是关心变量分布和变量之间的条件概率&#xff0c;如决策树&#xff0c;随机森林&#xff0c;…

ExoPlayer架构详解与源码分析(3)——Timeline

系列文章目录 ExoPlayer架构详解与源码分析&#xff08;1&#xff09;——前言 ExoPlayer架构详解与源码分析&#xff08;2&#xff09;——Player 文章目录 系列文章目录前言Timeline单文件或者点播流媒体文件播放列表或者点播流列表有限可播的直播流无限可播的直播流有多个P…

速度轴模拟量控制FB(博途SCL+三菱ST代码)

利用模拟量实现变频器的正反转直接控制具体方法,请参考下面文章链接: 模拟量0-10V信号控制变频器实现正反转速度随动_RXXW_Dor的博客-CSDN博客比例随动专栏有系列文章介绍,大家可以查看相关文章,链接如下:绕线机-排线伺服比例随动功能块(梯形图+SCL代码)_RXXW_Dor的博客…

Python如何实现数据驱动的接口自动化测试

大家在接口测试的过程中&#xff0c;很多时候会用到对CSV的读取操作&#xff0c;本文主要说明Python3对CSV的写入和读取。下面话不多说了&#xff0c;来一起看看详细的介绍吧。 1、需求 某API&#xff0c;GET方法&#xff0c;token,mobile,email三个参数 token为必填项mobil…

比特米盒子刷CoreELEC

CoreELEC就晶辰定制的Kodi版本&#xff0c;比特米盒子在刷入ATV后通过切换卡载系统可以安装CoreELEC即可安装&#xff0c;实现影音播放自由 1、U盘启动CoreELEC 1.1 、安装【安卓】切换卡载系统 通过U盘在已经刷好atv6.0的比特米盒子安装“切换卡载系统”。比特米盒子刷atv6.…

uni-app:js修改元素样式(宽度、外边距)

效果 代码 1、在<view>元素上添加一个ref属性&#xff0c;用于在JavaScript代码中获取对该元素的引用&#xff1a;<view ref"myView" id"mybox"></view> 2、获取元素引用 &#xff1a;const viewElement this.$refs.myView.$el; 3、修改…

【Zookeeper专题】Zookeeper特性与节点数据类型详解

目录 前言前置知识课程内容一、Zookeeper介绍二、Zookeeper快速开始2.1 Zookeeper安装2.2 客户端命令行操作2.3 GUI工具 三、Zookeeper数据结构3.1 ZNode节点分类3.2 ZNode状态信息3.3 监听机制详解3.3.1 永久性Watch 3.4 节点ZNode特性总结3.5 应用场景详解3.5.1 统一命名服务…

广西建筑模板厂家-能强优品木业

广西作为中国西南地区的重要省份&#xff0c;建筑业蓬勃发展&#xff0c;建筑模板作为建筑施工的核心材料之一&#xff0c;在广西也有着广泛的需求。如果您正在寻找广西的建筑模板厂家&#xff0c;广西贵港市能强优品木业有限公司是一家备受认可的供应商。广西贵港市能强优品木…

八、【快速选择工具组】

文章目录 对象选择工具快速选择工具魔棒工具 对象选择工具 当我们选择对象选择工具时&#xff0c;需要先注意上边有一个循环的圆&#xff0c;它会进行内容识别&#xff0c;当识别完成会停止旋转。这个时候我们按住n键&#xff0c;或者将鼠标放上对应的图形时会出现选中的颜色。…

5分钟入门卷积算法

大家好啊&#xff0c;我是董董灿。 深度学习算法中&#xff0c;尤其是计算机视觉&#xff0c;卷积是无论如何都绕不过去的槛。 初学者看到这个算法后&#xff0c;很多是知其然不知其所以然&#xff0c;甚至不知道这个算法是做什么的&#xff0c;或者很疑惑&#xff0c;为什么…

在vue2中,v-model和.sync的区别

最近在封装一个弹窗组件时&#xff0c;用了比较复杂的逻辑去做显示和隐藏的逻辑&#xff0c;在查看同事的代码之后&#xff0c;才知道还有更简单的方法&#xff0c;自己已经忘了一些API. popup组件里统一的template&#xff1a; <div v-ifisShowPopup> // 弹窗内容 <…

oringin的x轴(按x轴规定值)绘制不规律的横坐标

1.双击x轴 2.选择刻度线标签 3.选择刻度

网络安全行业真的内卷了吗?网络安全就业就业必看

前言 有一个特别流行的词语叫做“内卷”&#xff1a; 城市内卷太严重了&#xff0c;年轻人不好找工作&#xff1b;教育内卷&#xff1b;考研内卷&#xff1b;当然还有计算机行业内卷…… 这里的内卷当然不是这个词原本的意思&#xff0c;而是“过剩”“饱和”的替代词。 按照…

实验三十五、LM117 稳压电源的设计

一、题目 利用 LM117 设计一个稳压电路&#xff0c;要求输出电压的调节范围为 5 ∼ 20 V 5\sim20\,\textrm V 5∼20V&#xff0c;最大负载电流为 400 mA 400\,\textrm{mA} 400mA。利用 Multisim 对所设计电路进行仿真&#xff0c;并测试所有性能指标。 二、仿真电路 仿真电…

Waves 14混音特效插件合集mac/win

Waves14是一款音频处理软件&#xff0c;主要用于音频编辑、混音和母带处理。该软件提供了各种插件&#xff0c;包括EQ、压缩、混响、延迟、失真等&#xff0c;以及一些专业的音频处理工具&#xff0c;如L2限幅器、Linear Phase EQ和多频道扬声器管理。 Mac软件下载&#xff1a;…

深度学习基础 2D卷积(1)

什么是2D卷积 2D参数量怎么计算 以pytorch为例子&#xff0c;2D卷积在设置的时候具有以下参数&#xff0c;具有输入通道的多少&#xff08;这个决定了卷积核的通道数量&#xff09;&#xff0c;滤波器数量&#xff0c;这个是有多少个滤波器&#xff0c;越多提取的特征就越有用…

10.1select并发服务器以及客户端

服务器&#xff1a; #include<myhead.h>//do-while只是为了不让花括号单独存在&#xff0c;并不循环 #define ERR_MSG(msg) do{\fprintf(stderr,"%d:",__LINE__);\perror(msg);\ }while(0);#define PORT 8888//端口号1024-49151 #define IP "192.168.2.5…

在Linux上安装QQ

第一步&#xff1a; 在QQ官网上复制Linux版QQ的下载链接 https://dldir1.qq.com/qqfile/qq/QQNT/b69de82d/linuxqq_3.2.1-17153_x86_64.rpm 第二步&#xff1a; 在Linux终端输入wget 加Linux版QQ的下载链接&#xff08;如果怕中途断开链接可以输入wget -c &#xff09; [rootn…