spring boot3登录开发-邮箱登录/注册接口实现
⛰️个人主页: 蒾酒
🔥系列专栏:《spring boot实战》
🌊山高路远,行路漫漫,终有归途
目录
写在前面
上文衔接
内容简介
功能分析
所需依赖
邮箱验证登录/注册实现
1.创建交互对象
2.登录注册业务逻辑实现
最近发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。
点击跳转到学习网站
写在前面
本文介绍了springboot开发后端服务中,邮箱验证码登录/注册功能的设计与实现,坚持看完相信对你有帮助。
同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。
上文衔接
本文衔接上文,可以看一下:
spring boot3登录开发-邮件验证码接口实现-CSDN博客
用户表设计如下:
create table user
(id bigint auto_increment comment '主键'primary key,user_name varchar(32) null comment '用户昵称',password varchar(255) null comment '密码',account varchar(64) null comment '账号',user_role varchar(252) default 'user' null comment '用户角色:user / admin',avatar varchar(1024) null comment '头像',create_time datetime default (now()) null comment '创建时间',update_time datetime default CURRENT_TIMESTAMP null comment '更新时间',is_delete tinyint(1) default 0 null comment '逻辑删除:1删除/0存在',gender tinyint(1) null comment '性别',user_signature varchar(255) null comment '个性签名',status tinyint(1) default 1 not null comment '状态:1正常0禁用',phone varchar(11) null comment '手机号',email varchar(100) null comment '邮箱'
)comment '用户表';
内容简介
上文我们已经实现了邮件验证码的发送接口,本文我们来实现这个邮箱验证登录/注册逻辑。
功能分析
- 邮箱未注册过则先注册,注册完执行登录
- 已经注册过的邮箱,直接执行登录
所需依赖
redis
Spring Boot3整合Redis_springboot3整合redis-CSDN博客
邮箱验证登录/注册实现
1.创建交互对象
用户登录/注册DTO:
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;/*** @author mijiupro*/
@Data
public class UserEmailLoginDTO {@NotBlank(message = "邮箱不能为空")@Pattern(regexp = "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$", message = "邮箱格式不正确")private String email;@NotBlank( message = "验证码不能为空")private String captcha;}
这里用Lombok的@Data来生成getter和setter。
这里用spring boot参数验证组件来检验参数格式:
spring boot3参数校验基本用法_springboot3使用校验类注解-CSDN博客
用户登录VO:
import lombok.Builder;
import lombok.Data;import java.io.Serializable;/*** @author mijiupro*/
@Data
@Builder
public class UserLoginVO implements Serializable {private String token;//令牌private String userName;//用户名private String avatar;//头像
}
2.登录注册业务逻辑实现
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.mijiu.commom.enumerate.ResultEnum;
import com.mijiu.commom.exception.*;
import com.mijiu.commom.model.dto.UserEmailLoginDTO;
import com.mijiu.commom.model.vo.UserLoginVO;
import com.mijiu.commom.util.JwtUtils;
import com.mijiu.entity.User;
import com.mijiu.mapper.UserMapper;
import com.mijiu.service.UserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.util.Map;
import java.util.Objects;/*** <p>* 用户表 服务实现类* </p>** @author 蒾酒* @since 2024-02-03*/
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {private final UserMapper userMapper;private final JwtUtils jwtUtils;private final StringRedisTemplate stringRedisTemplate;public UserServiceImpl(UserMapper userMapper, JwtUtils jwtUtils, StringRedisTemplate stringRedisTemplate) {this.userMapper = userMapper;this.jwtUtils = jwtUtils;this.stringRedisTemplate = stringRedisTemplate;}@Overridepublic UserLoginVO emailLogin(UserEmailLoginDTO userEmailLoginDTO) {// 校验验证码是否存在HashOperations<String, String, String> hashOps = stringRedisTemplate.opsForHash();String captcha = hashOps.get("login:email:captcha:" + userEmailLoginDTO.getEmail(), "captcha");if (StringUtils.isEmpty(captcha)) {log.error("手机号 {} 的验证码不存在或已过期", userEmailLoginDTO.getEmail());throw new CaptchaErrorException(ResultEnum.USER_CAPTCHA_NOT_EXIST);}// 查询用户是否已注册User loginUser = new LambdaQueryChainWrapper<>(userMapper).eq(User::getPhone, userEmailLoginDTO.getEmail()).one();// 如果未注册则进行注册if (Objects.isNull(loginUser)) {loginUser = registerByEmail(userEmailLoginDTO.getEmail());}// 校验验证码是否正确if (!userEmailLoginDTO.getCaptcha().equals(captcha)) {log.error("邮箱号 {} 的验证码错误", userEmailLoginDTO.getEmail());throw new CaptchaErrorException(ResultEnum.AUTH_CODE_ERROR);}//判断用户是否被禁用if (!loginUser.getStatus()) {throw new AccountForbiddenException(ResultEnum.USER_ACCOUNT_FORBIDDEN);}log.info("手机号 {} 用户登录成功",userEmailLoginDTO.getEmail());return UserLoginVO.builder().token(jwtUtils.generateToken(Map.of("userId", loginUser.getId()), "user")).userName(loginUser.getUserName()).build();}// 用户邮箱注册private User registerByEmail(String email) {User user = new User();user.setEmail(email);user.setUserName(email);user.setStatus(true);if (userMapper.insert(user) < 1) {log.error("邮箱 {} 用户注册失败!", email);throw new AccountRegisterFailException(ResultEnum.USER_REGISTER_FAIL);}log.info("邮箱 {} 用户注册成功", email);return user;}
}
4.测试接口
使用swagger3进行测试
Spring Boot3整合knife4j(swagger3)_springboot3 knife4j-CSDN博客
调用邮箱验证码发送接口
调用邮箱验证登录接口
第一次登录所以也就自动注册成功了。
写在最后
springboot实现邮箱验证登录注册到这里就结束了,本文介绍了一种通用的邮箱验证登录实现方式,代码逻辑清晰。任何问题评论区或私信讨论,欢迎指正。
相关文章:
spring boot3登录开发-邮箱登录/注册接口实现
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途 目录 写在前面 上文衔接 内容简介 功能分析 所需依赖 邮箱验证登录/注册实现 1.创建交互对象 2.登录注册业务逻辑实…...
数据结构-二叉搜索树
二叉搜索树:BST(Binary Search Tree) 二叉搜索树是二叉树,可以为空,如果不为空,满足以下性质: 非空左子树的所有键值小于其根节点的键值非空右子树的所有键值大于其根节点的键值左、右字数本身也都是二叉搜索树 二叉…...
JUnit:Java开发者不可或缺的单元测试框架
在软件开发过程中,测试是确保代码质量的关键环节。单元测试作为测试体系的基础,对提升代码质量、降低bug率、增强软件稳定性具有重要作用。JUnit 作为 Java 语言事实上的标准单元测试框架,已经成为 Java 开发者进行单元测试的首选工具。本文将…...
NG32单片机GPIO口配置方式
目录 一、引言 二、GPIO口基本结构 三、GPIO口配置方式 四、工作原理 五、总结 一、引言 NG32单片机是一款集成度高、功能强大的微控制器。其中,GPIO(General Purpose Input/Output)口作为单片机与外部设备通信的重要接口,具…...
SpringCloud-OpenFeign拓展-连接池、最佳使用方法、日志输出
目录 1 OpenFeign连接池 1.1 常见连接类型 1.2 连接池使用方法 1.2.1 引入依赖 1.2.2 开启连接池功能 1.2.3 配置完成,重启实例即可,底层将更改设置。 2 OpenFeign最佳使用方法 2.1 每个微服务都是单独的project,内部有三个独立模块 …...
跨链协议中Cosmos IBC、Polkadot/XCM、Celer Network的区别以及用途
跨链协议是实现不同区块链之间通信和价值转移的关键技术。Cosmos IBC、Polkadot/XCM 和 Celer Network 是三个在跨链领域内具有代表性的协议,它们各自有着独特的设计理念和应用场景。下面是这三个协议的详细对比: Cosmos IBC (Inter-Blockchain Communi…...
电子画册制作与传统画册相比,有哪些优势?
在当今数字化时代,电子画册作为一种新兴的媒体形式,其制作与传统画册相比具有显著的优势。以下是对这些优势的详细探讨。 首先,电子画册的制作过程通常更加便捷和经济。相较于传统画册需要经历的繁琐的印刷过程,电子画册的制作大多…...
postman如何导入证书
1、打开postman,点击Settings。 2、添加证书。 3、填写要访问平台的URL路径及端口、证书文件、证书密码。 4、添加完之后即可立即调用postman。...
RocketMQ教程(八):RocketMQ的集群搭建
传送门:RocketMQ教程汇总,让你从入门到精通 集群架构 RocketMQ 的各个组件都可以搭建成集群部署,Broker 还可以搭建成主从架构,下面介绍的主要是 Broker 集群。 数据复制策略 复制策略是Broker的Master与Slave间的数据同步方式。分为同步复制与异步复制: 同步复制 消…...
线上观看人次2万+!「飞天技术沙龙-CentOS 迁移替换专场」北京站圆满结束
5 月 29 日,阿里云联合龙蜥社区共同举办的「飞天技术沙龙-CentOS 迁移替换专场」于北京圆满结束,在线观看人次 2 万。本次活动现场汇聚了来自浪潮信息、Intel、龙芯、统信软件、红旗软件、电子五所等多家操作系统产业头部企业和机构,大家围绕…...
Docker基本架构概览-1
Docker基本架构概览 Docker架构 Docker采用客户端-服务器(C/S)架构,主要组件包括: Docker Client 用户与Docker交互的接口,发送命令到Docker守护进程。 Docker Daemon 运行在后台,接收并处理Docker客户端…...
OZON云仓靠谱吗,OZON云仓垫资提货模式
在电商飞速发展的今天,物流仓储成为了支撑整个电商生态的重要基石。OZON云仓作为市场上新兴的仓储物流服务提供商,凭借其先进的技术和灵活的服务模式,受到了不少电商卖家和消费者的关注。但随之而来的是一系列疑问:OZON云仓靠谱吗…...
数据集笔记:DGraph 大规模动态图数据集
dgraph-web (xinye.com) 1 数据集介绍 DGraph 是一个有向无权的动态图,包含超过 370 万个节点以及 430 万条动态边DGraph 中的节点表示金融借贷用户,有向边表示紧急联系人关系,每个节点包含脱敏后的属性特征,以及表示是否为金融…...
一些常用的git指令总结
1、git add 文件名 :该 命令可将该文件的修改添加到暂存区 比如:我刚刚修改了my_test.cpp文件,这时就可以使用git add my_test.cpp. 就将该修改添加到了暂存区。 2、git commit -m "......说明" 就是将当前的修改记录提交到本地…...
【HarmonyOS】遇见的问题汇总
一、当前编辑的页面,预览打不开 1、问题说明 当前编辑的页面,预览打不开,日志提示如下: Route information is not configured for the current page. To avoid possible redirection issues, configure route information for…...
C# NX二次开发-获取圆弧中心点和半径
使用UF函数可以获取圆弧边或圆弧线中心点和半径: 1.使用 UF_CURVE_ask_arc_data: theUf.Curve.AskArcData(edge.Tag, out UFCurve.Arc arc);theUf.Curve.CreateArc(ref arc, out Tag arc_tag);double[] matrix_values new double[9];double[] vec_product new double[3];theU…...
鸿蒙原生应用元服务开发-位置服务地理编码转化开发
(逆)地理编码转化开发 场景概述 使用坐标描述一个位置,非常准确,但是并不直观,面向用户表达并不友好。系统向开发者提供了以下两种转化能力。 地理编码转化:将地理描述转化为具体坐标。 逆地理编码转化能力…...
【ArcGISPro SDK】构建多面体要素
结果展示 每个面构建顺序 代码 using ArcGIS.Core.CIM; using ArcGIS.Core.Data; using ArcGIS.Core.Geometry; using ArcGIS.Desktop.Catalog; using ArcGIS.Desktop.Core; using ArcGIS.Desktop.Editing; using ArcGIS.Desktop.Extensions; using ArcGIS.Desktop.Framework;…...
leetcode够用之java语法
常用方法 Arrays.sort()排序 import java.util.Arrays;public class Main {public static void main(String[] args) {int[] numbers {9, 2, 5, 1, 7, 3};Arrays.sort(numbers);System.out.println(Arrays.toString(numbers)); // 输出: [1, 2, 3, 5, 7, 9]} }获取str中的第…...
pdf文件怎么改变大小?在线快速压缩pdf的方法
pdf作为一种常用的文件格式,使用这种文件类型的好处在于不仅拥有更好的兼容性,还可以设置密码来保证安全性,防止未授权用户查看内容,所以现在导出文件展示都会采用这种格式的来做内容展示。当遇到pdf文件过大问题时,想…...
inferCNV:scRNA-seq数据推断染色体拷贝数变化
inferCNV分析简介 inferCNV用于探索肿瘤单细胞RNA-Seq 数据,以确定体细胞大规模染色体拷贝数改变的证据,例如整个染色体或大片段染色体的增益或缺失。这是通过与一组参考“正常”细胞(这里的正常细胞可自行定义)进行比较…...
银河麒麟操作系统通过首批软件供应链安全能力认证
麒麟软件产品供应链安全能力获双重肯定!5月30日,经北京赛迪认证中心评估,银河麒麟高级服务器操作系统V10和银河麒麟桌面操作系统V10成为首批获得软件供应链安全能力认证产品,并在操作系统类产品中名列前茅。 软件供应链安全能力评…...
【MySQL】数据库介绍|数据库分类|MySQL的基本结构|MySQL初步认识|SQL分类
目录 数据库介绍 什么是数据库 数据库分类 1.关系型数据库(RDBMS): 2.非关系型数据库: MySQL要学啥 MySQL初步认识 SQL分类 💡推荐 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风…...
2024年6月11日 (周二) 叶子游戏新闻
万能嗅探: 实测 网页打开 某视频号、某音、某红薯、某站,可以做到无水印的视频和封面下载功能哦,具体玩法大家自行发挥吧。 WPS免登录一键修改器: 去除烦人的登录且能正常使用 日本一首部游戏《拼图世界》上架Steam 30年PS名作日本游戏厂商日本一的首部品…...
JavaSE----类和对象(中)
5. 对象的构造及初始化 5.1 如何初始化对象 通过前面知识点的学习知道,在Java方法内部定义一个局部变量时,必须要初始化,否则会编译失败。 public static void main(String[] args) {int a;System.out.println(a); }// Error:(26, 28) jav…...
STC8增强型单片机进阶开发--OLED显示器(SPI)
系列文章目录 提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加 例如:第一章 Python 机器学习入门之pandas的使用 提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目…...
在CSS中,可以使用 float 属性来设置元素浮动
在CSS中,可以使用float属性来设置元素浮动。float属性有三个值:left、right和none。 float: left;:将元素浮动到左侧。float: right;:将元素浮动到右侧。float: none;:取消元素的浮动(默认值)。…...
wordpress主题开发
科普一:wordpress 是一套用 php 这个语言写的CMS后台管理系统,即我们大家的 wordpress 网站后台是一样的,能体现我们网站外观不同的地方就在于wordpress主题(即皮肤),而这个主题的基本构成是 htmlcssjavasc…...
Elasticsearch 认证模拟题 - 17
这两道题目非常具有代表性,分别是跨集群复制和跨集群检索,需要相应的 许可 这里在虚拟机上搭建集群完成这两道题目,这里补充一下 elasticsearch 和 kibana 的配置文件 # elasticsearch.yml cluster.name: cluster2 node.name: cluster2-node…...
Swift 中更现代化的调试日志系统趣谈(一)
概述 昨天凌晨苹果刚刚发布了 WWDC2024 一系列新视频,这标志着苹果开发的一只脚已迈入人工智能(Apple Intelligence)的崭新时代。即便如此,我相信不少秃头码农们还在使用一些“远古简陋”的调试方法来剖析 2142 年的代码。 不过别担心,这一切将在小伙伴们学完本系列博文后…...
做网站外包哪家好/网络营销类型有哪些
前言安全保护几乎对于所有的项目都是一个挑战,对于物联网项目更是如,自普及应用以来物联网业内已经发生过多起安全事故。作为物联网通信协议事实标准,MQTT 保持着较高的安全性,提供了多层次的安全设计:传输层ÿ…...
做网站的软件dw/免费建网站
PPP-C#conf tPPP-C(config)#vpdn enable //启用路由器的虚拟专用拨号网络---***d 由于ADSL的PPPoE应用是通过虚拟拨号来实现的所以在路由器中需要使用VPDN的功能PPP-C(config)#int e1/0 // 路由器内网接口PPP-C(config-if)#no shutPPP-C(config-if)#i…...
qq营销/东莞网络优化公司
一大早,U-Mail客服张小姐就被电话催得迅速进入工作状态,原来一位客户心急火燎的说邮件往外界投递失败,但不知什么原因?张小姐迅速联系到客户专享技术工程师刘工,迅速对客户进行远程诊断,即刻排除了故障&…...
学校网站怎么建设/想学销售去哪培训
气候类 1、北京日均最低气温 var bj_temp_ low [-6,-4,3,10,16,21,24,23,17,9,1,-5]2、北京日均最高气温 var bj_temp_ hight [3,6,15,23,29,32,33,32,27,19,10,4]3、北京历史最高气温 var bj_temp_ max [24,19,29,34,38,38,39,36,32,28,24,28]4、北京历史最低气温 var …...
微网站费用/泰安百度推广公司
喜欢文章内容可以点个赞❤支持一下,更多内容请关注老毕浏览器如果你想了解更多好用的浏览器可以参考下面的这篇文章毕达哥拉斯:2020你值得拥有的浏览器zhuanlan.zhihu.com今天介绍的七款浏览器有Google Chrome、Mozilla Firefox、Cent Browser…...
app制作教程简单易学/seo流量
刚做了,蓝桥杯算法训练的最大最小公倍数一题,感觉考查的是数学了,哈哈。 时间限制:1.0s 内存限制:256.0MB 问题描述 已知一个正整数N,问从1~N中任选出三个数,他们的最小公倍数最大可以为多少。…...