上海html5网站制作公司,长沙旅游必去的八个景点,wordpress做电商网站,大型做网站⛰️个人主页: 蒾酒
#x1f525;系列专栏#xff1a;《spring boot实战》
#x1f30a;山高路远#xff0c;行路漫漫#xff0c;终有归途 目录
写在前面
上文衔接
内容简介
功能分析
短信验证登录实现
1.创建交互对象
用户短信登录/注册DTO
创建用户登录VO…
⛰️个人主页: 蒾酒
系列专栏《spring boot实战》
山高路远行路漫漫终有归途 目录
写在前面
上文衔接
内容简介
功能分析
短信验证登录实现
1.创建交互对象
用户短信登录/注册DTO
创建用户登录VO
2.创建自定义业务异常
创建验证码错误异常
创建用户被封禁异常 创建用户注册失败异常
3.登录注册业务逻辑实现
4.测试接口
调用短信验证码发送接口
调用短信验证登录接口
写在最后 写在前面
本文介绍了springboot开发后端服务中短信验证码登录功能的设计与实现坚持看完相信对你有帮助。
同时欢迎订阅springboot系列专栏持续分享spring boot的使用经验。 上文衔接
本文衔接上文可以看一下
spring boot3登录开发-2(2短信验证码接口实现-CSDN博客https://blog.csdn.net/qq_62262918/article/details/136888851?spm1001.2014.3001.5501
用户表设计如下
create table user
(id bigint auto_increment comment 主键primary key,user_name varchar(32) null comment 用户昵称,password varchar(256) null comment 密码,user_account varchar(64) null comment 账号,user_role varchar(256) 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 性别,status tinyint(1) default 1 not null comment 状态1正常0禁用,phone varchar(11) null comment 手机号
)comment 用户表; 内容简介
上文我们已经实现了短信验证码的发送接口本文我们来实现这个短信验证登录/注册逻辑。 功能分析 手机号是新手机号则先注册注册完执行登录已经注册过的手机号直接执行登录 短信验证登录实现
1.创建交互对象
用户短信登录/注册DTO
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;/*** author mijiupro*/
Data
public class UserSmsLoginDTO {NotBlank( message 手机号不能为空)Pattern(regexp ^1[3456789]\\d{9}$, message 手机号格式不正确)private String phone;//手机号NotBlank( message 验证码不能为空)private String captcha;//验证码
}创建用户登录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.创建自定义业务异常
说白了就是登录代码可能会判断账号是否存在,密码是否正确当账号不存在或密码错误需要返回对应提示信息这种类似情况多了你的代码就会很多if-return,代码就会很难看那么通过自定义异常去到异常处理的方法里面写对应返回提示以及其他逻辑这样直接抛出对应异常AOP拦截到该异常走对应异常处理逻辑即可。(一句话概括就是把处理特殊业务异常情况的代码逻辑抽取出来放到别的类里面写可以使代码更加清晰和可维护) 创建验证码错误异常
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Getter;/*** author mijiupro*/
Getter
public class CaptchaErrorException extends RuntimeException {private final ResultEnum resultEnum;//返回提示信息枚举(code,message)public CaptchaErrorException(ResultEnum resultEnum) {this.resultEnum resultEnum;}
}
创建用户被封禁异常
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Getter;/*** author mijiupro*/
Getter
public class AccountForbiddenException extends RuntimeException {private final ResultEnum resultEnum;public AccountForbiddenException(ResultEnum resultEnum) {this.resultEnum resultEnum;}
} 创建用户注册失败异常
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Getter;/*** author mijiupro*/
Getter
public class AccountRegisterFailException extends RuntimeException {private final ResultEnum resultEnum;//返回提示信息枚举(code,message)public AccountRegisterFailException(ResultEnum resultEnum) {this.resultEnum resultEnum;}
} 3.登录注册业务逻辑实现
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.UserLoginDTO;
import com.mijiu.commom.model.dto.UserSmsLoginDTO;
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 ServiceImplUserMapper, 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 SmsLogin(UserSmsLoginDTO userSmsLoginDTO) {// 校验验证码是否存在HashOperationsString, String, String hashOps stringRedisTemplate.opsForHash();String captcha hashOps.get(login:sms:captcha: userSmsLoginDTO.getPhone(), captcha);if (StringUtils.isEmpty(captcha)) {log.error(手机号 {} 的验证码不存在或已过期, userSmsLoginDTO.getPhone());throw new CaptchaErrorException(ResultEnum.USER_CAPTCHA_NOT_EXIST);}// 查询用户是否已注册User loginUser new LambdaQueryChainWrapper(userMapper).eq(User::getPhone, userSmsLoginDTO.getPhone()).one();// 如果未注册则进行注册if (Objects.isNull(loginUser)) {loginUser register(userSmsLoginDTO.getPhone());}// 校验验证码是否正确if (!userSmsLoginDTO.getCaptcha().equals(captcha)) {log.error(手机号 {} 的验证码错误, userSmsLoginDTO.getPhone());throw new CaptchaErrorException(ResultEnum.AUTH_CODE_ERROR);}//判断用户是否被禁用if (!loginUser.getStatus()) {throw new AccountForbiddenException(ResultEnum.USER_ACCOUNT_FORBIDDEN);}log.info(手机号 {} 用户登录成功, userSmsLoginDTO.getPhone());return UserLoginVO.builder().token(jwtUtils.generateToken(Map.of(userId, loginUser.getId()), user)).userName(loginUser.getUserName()).build();}private User register(String phone) {User user new User();user.setPhone(phone);user.setUserName(phone);user.setStatus(true);if (userMapper.insert(user) 1) {log.error(手机号 {} 用户注册失败, phone);throw new AccountRegisterFailException(ResultEnum.USER_REGISTER_FAIL);}log.info(手机号 {} 用户注册成功, phone);return user;}
}
4.测试接口
使用swagger3进行测试
Spring Boot3整合knife4j(swagger3)_springboot3 knife4j-CSDN博客文章浏览阅读2.3k次点赞39次收藏54次。Knife4j · 集Swagger2及OpenAPI3为一体的增强解决方案. | Knife4j (xiaominfo.com)作者的使用的spring boot 3.2.2为当前最新版所以依赖导入最新的knife4j 4.4.0。3.1 增强模式 | Knife4j (xiaominfo.com)好一个spring boot项目且版本为3X项目可正常启动。快速开始 | Knife4j (xiaominfo.com)接下来配置以下接口文档的作者等信息。Tag注解标记接口类别。_springboot3 knife4jhttps://blog.csdn.net/qq_62262918/article/details/135761392?spm1001.2014.3001.5502
调用短信验证码发送接口 调用短信验证登录接口 第一次登录所以也就自动注册成功了。 写在最后
springboot实现短信验证登录注册到这里就结束了本文介绍了一种通用的短信验证登录实现方式代码逻辑清晰。任何问题评论区或私信讨论欢迎指正。