spring boot3登录开发-邮箱登录/注册接口实现

⛰️个人主页: 蒾酒

🔥系列专栏:《spring boot实战》

🌊山高路远,行路漫漫,终有归途


目录

写在前面

上文衔接

内容简介

功能分析

所需依赖

邮箱验证登录/注册实现

1.创建交互对象

2.登录注册业务逻辑实现


最近发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

点击跳转到学习网站

写在前面

本文介绍了springboot开发后端服务中,邮箱验证码登录/注册功能的设计与实现,坚持看完相信对你有帮助。

同时欢迎订阅springboot系列专栏,持续分享spring boot的使用经验。

上文衔接

本文衔接上文,可以看一下:

spring boot3登录开发-邮件验证码接口实现-CSDN博客

用户表设计如下:

sql 复制代码
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:

java 复制代码
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:

java 复制代码
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.登录注册业务逻辑实现

java 复制代码
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;
    }
    
    @Override
    public 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实现邮箱验证登录注册到这里就结束了,本文介绍了一种通用的邮箱验证登录实现方式,代码逻辑清晰。任何问题评论区或私信讨论,欢迎指正。

相关推荐
罗政2 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
架构文摘JGWZ3 小时前
Java 23 的12 个新特性!!
java·开发语言·学习
拾光师4 小时前
spring获取当前request
java·后端·spring
aPurpleBerry4 小时前
neo4j安装启动教程+对应的jdk配置
java·neo4j
我是苏苏4 小时前
Web开发:ABP框架2——入门级别的增删改查Demo
java·开发语言
xujinwei_gingko4 小时前
Spring IOC容器Bean对象管理-Java Config方式
java·spring
2301_789985944 小时前
Java语言程序设计基础篇_编程练习题*18.29(某个目录下的文件数目)
java·开发语言·学习
IT学长编程4 小时前
计算机毕业设计 教师科研信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·毕业设计·springboot·毕业论文·计算机毕业设计选题·计算机毕业设计开题报告·教师科研管理系统
m0_571957584 小时前
Java | Leetcode Java题解之第406题根据身高重建队列
java·leetcode·题解
程序猿小D5 小时前
第二百三十五节 JPA教程 - JPA Lob列示例
java·数据库·windows·oracle·jdk·jpa