Spring Boot + Mybatis Plus实现登录注册

news2024/11/28 16:05:00

Spring Boot 实现登录注册

1. 注册

业务逻辑

  1. 客户端输入注册时需要的用户参数,比如:账户名、密码、确认密码、其他
  2. 服务端接收到客户端的请求参数进行校验,然后判断是否有误,有误的地方就将错误信息抛出
  3. 将密码进行加密之后存储到数据库中,切记不能以明文的方式存入
  4. 返回用户的id作为注册成功之后的返回信息

具体实现 + 代码

  1. controller 层

    • 封装请求参数 UserRegisterRequest
    • 判断请求参数是否为空
    • 调用service的注册方法将请求参数传递给注册方法
    @PostMapping("/register")
        public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userLoginRequest) {
            if(userLoginRequest == null) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            String userAccount = userLoginRequest.getUserAccount();
            String userPassword = userLoginRequest.getUserPassword();
            String checkPassword = userLoginRequest.getCheckPassword();
            if(StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            long result = userService.userRegister(userAccount, userPassword, checkPassword);
            return ResultUtils.success(result);
        }
    
  2. service 层

    • 判断请求参数对象是否为空 使用 StringUtils工具进行判断[需要下载org.apache.commons-lang3依赖]
    • 校验参数:
      • 账户名长度 < 3
      • 密码长度 < 4
      • 密码和确认密码是否相等
      • 用户名、密码、确认密码是否为空
    • 创建一个查询对象来确保账户是唯一的不能重复注册
    • 密码加密
    • 创建一个user对象,将用户信息存储到数据库中
    @Override
        public long userRegister(String userAccount, String userPassword, String checkPassword) {
            if(StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR);
            }
            if(userAccount.length() < 3) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账户名长度太短");
            }
            if(userPassword.length() < 4) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码长度太短");
            }
            if(!userPassword.equals(checkPassword)) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "校验密码不相等");
            }
            // 加锁防止恶意注册操作
            synchronized (userAccount.intern()) {
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("userAccount", userAccount);
                Long count = this.baseMapper.selectCount(queryWrapper);
                if (count > 0) {
                    throw new BusinessException(ErrorCode.PARAMS_ERROR, "该账号已注册");
                }
                String newUserPassword = DigestUtils.md5DigestAsHex((SLAT + userPassword).getBytes());
                User user = new User();
                user.setUserAccount(userAccount);
                user.setUserPassword(newUserPassword);
                boolean save = this.save(user);
                if (!save) {
                    throw new BusinessException(ErrorCode.OPERATION_ERROR, "用户注册失败");
                }
                return user.getId();
            }
        }
    
  3. 测试

    image-20240606111153586

    通过观察服务器的响应,可以看到当前用户信息注册成功

    image-20240606111300500

    数据库中也能查询到该条用户数据

2. 登录

业务逻辑

  1. 用户输入登录时需要传递的参数:用户名、密码
  2. 服务器收到参数之后取出进行校验
  3. 创建一个queryWrapper进行查询,查询当前账户是否是唯一的,不允许未被注册就能登录的情况
  4. 将用户的登录信息存储到登录态中
  5. 返回脱敏后的用户信息

具体实现 + 代码

  1. controller层

    • 封装一个用户登录请求的类,里面用于存入用户登陆时的请求参数

    • 取出所有参数判断是否为空

    • 调用service层中用户登录的方法

      @PostMapping("/login")
      public BaseResponse<UserLoginVO> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
          if(userLoginRequest == null) {
              throw new BusinessException(ErrorCode.PARAMS_ERROR);
          }
          String userAccount = userLoginRequest.getUserAccount();
          String userPassword = userLoginRequest.getUserPassword();
          if(StringUtils.isAnyBlank(userAccount, userPassword)) {
              throw new BusinessException(ErrorCode.PARAMS_ERROR);
          }
          UserLoginVO result = userService.userLogin(userAccount, userPassword, request);
          return ResultUtils.success(result);
      }
      
  2. service层

    • 校验参数是否为空

    • 创建一个queryWrapper进行查询,是否有和当前账户和密码一致的数据库信息(注意这里的密码必须是加密之后的密码进行查询,否则会查不到)

    • 不存在的话就说明当前用户未注册

    • 将用户信息存储到登录态中

    • 返回脱敏之后的用户信息

      @Override
      public UserLoginVO userLogin(String userAccount, String userPassword, HttpServletRequest request) {
          // 1. 对参数进行校验 账户和密码是否为空
          if(StringUtils.isAnyBlank(userAccount, userPassword)) {
              throw new BusinessException(ErrorCode.PARAMS_ERROR);
          }
          // 2. 将用户的密码进行加密 有的话就登录成功    查询数据库中的账户是否存在   不存在就报错
          String md_userPassword = DigestUtils.md5DigestAsHex((SLAT + userPassword).getBytes());
          QueryWrapper<User> queryWrapper = new QueryWrapper<>();
          queryWrapper.eq("userAccount", userAccount);
          queryWrapper.eq("userPassword", md_userPassword);
          User user = this.baseMapper.selectOne(queryWrapper);
          if(user == null) {
              throw new BusinessException(ErrorCode.PARAMS_ERROR, "当前用户未注册");
          }
          // 3. 将用户信息存储到登录态中
          request.getSession().setAttribute(USER_LOGIN_STATE, user);
          // 3. 返回当前用户的所有信息(脱敏返回)
          return this.getUserLoginVO(user);
      }
      
  3. 测试

    输入前面我们注册的用户信息进行登录测试

    image-20240612185837959

    可以看出我们的登录功能是没有问题的,并且我们的request中也存储了用户的登录态信息

    image-20240612190111775

总结:

​ 注册登录是一个软件的基本功能,主要需要注意里面service层中的校验逻辑,我这里的校验比较的简单,只是实现了基础的东西,如果更复杂的应用可能会有更加严格细致的校验。后续大家也可以考虑进行扩展,比如:将用户的登录信息存储存储到session中实现多个客户端共享一个用户的信息,不用重复登录;另外也可以考虑将用户的登录改为单设备登录,这适用于一些用户充值了vip之后只能在单设备登录的场景。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光伏项目管理——数字化改革

随着全球对可再生能源的迫切需求以及环保意识的日益增强&#xff0c;光伏产业作为清洁能源的重要组成部分&#xff0c;正迎来快速发展的黄金时期。然而&#xff0c;传统的光伏项目管理方式已逐渐无法满足现代化、高效化的需求&#xff0c;数字化改革成为了行业发展的必然趋势。…

什么是无头浏览器以及其工作原理?

如果您对这个概念还不熟悉&#xff0c;那么使用无头网络浏览器的想法可能会让您感到不知所措。无头浏览器本质上与您熟悉的网络浏览器相同&#xff0c;但有一个关键区别&#xff1a;它们没有图形用户界面 (GUI)。这意味着没有按钮、选项卡、地址栏或视觉显示。 相反&#xff0c…

Tuxera NTFS for Mac 2023软件:超级详细安装步骤(最新版软件下载)

软件简介&#xff1a; 在 Mac 上打开、编辑、复制、移动或删除存储在 Windows NTFS 格式 USB 驱动器上的文件。当您获得一台新 Mac 时&#xff0c;它只能读取 Windows NTFS 格式的 USB 驱动器。要将文件添加、保存或写入您的 Mac&#xff0c;您需要一个附加的 NTFS 驱动程序。…

checkbox表单校验 至少选中一个Checkbox , 否则会报错

项目背景 : react ant 需求 : 需实现至少选中一个Checkbox , 否则会报错 需求如下 : 注意 : Input, Select, DatePicker可以直接处理Form.Item的验证规则 , 但Checkbox不行 , 需自定义验证规则 实现 : // 自定义的checkbox校验规则--星期const validateAtLeastOneCheckbo…

CP AUTOSAR标准中文文档链接索引

AUTOSAR标准的核心组件包括通信、诊断、安全等&#xff0c;这些组件通过模块化结构进行组织。系统被划分为多个模块&#xff0c;每个模块负责特定的功能。模块之间通过接口进行通信&#xff0c;接口定义了模块之间的交互规则。AUTOSAR标准支持模块的配置&#xff0c;可以根据不…

加密经济时代:Web3如何改变我们的生活方式

随着区块链技术的蓬勃发展和加密经济的兴起&#xff0c;Web3正逐渐成为数字化时代的主流趋势之一。作为下一代互联网的代表&#xff0c;Web3以其去中心化、安全可信的特性&#xff0c;正在改变着我们的生活方式。本文将深入探讨加密经济时代下&#xff0c;Web3如何改变了我们的…

形如SyntaxError: EOL while scanning string literal,以红色波浪线形式在Pycharm下出现

背景&#xff1a; 新手在学习Python时可能会出现如下图所示的报错 下面分情况教大家如何解决 视频教程【推荐】&#xff1a; 形如SyntaxError: EOL while scanning string literal&#xff0c;以红色波浪线形式在Pycharm下出现 过程&#xff1a; 问题概述&#xff1a; 简单…

鸿蒙开发文件管理:【@ohos.securityLabel (数据标签)】

数据标签 该模块提供文件数据安全等级的相关功能&#xff1a;向应用程序提供查询、设置文件数据安全等级的JS接口。 说明&#xff1a; 本模块首批接口从API version 9开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import security…

C# WinForm —— 34 ToolStrip 工具栏 介绍

1. 简介 工具栏 ToolStrip&#xff0c;一般紧贴在菜单栏下面 2. 属性 属性解释(Name)控件ID&#xff0c;在代码里引用的时候会用到Enabled控件是否启用Dock定义要绑定到容器的控件边框&#xff0c;默认是topAnchor定义某个控件绑定到的容器的边缘。当控件锚定到某个边缘时&a…

C++基础编程100题-009 OpenJudge-1.3-07 计算多项式的值

更多资源请关注纽扣编程微信公众号 http://noi.openjudge.cn/ch0103/07/ 描述 对于多项式 f ( x ) a x 3 b x 2 c x d f(x) ax^3 bx^2 cx d f(x)ax3bx2cxd 和给定的a, b, c, d, x&#xff0c;计算f(x)的值。 输入 输入仅一行&#xff0c;包含5个实数&#xff0c;分…

LeetCode | 66.加一

这道题有多个思路&#xff0c;可以依次取数组的每一位&#xff0c;乘10后加下一位&#xff0c;直到最后一位&#xff0c;就得到我们数组所表示的数字&#xff0c;然后加一&#xff0c;然后把新得到的数字再转化为对应的数组&#xff0c;我的做法是直接取数组的最后一位&#xf…

redis 07 订阅

订阅频道 订阅模式&#xff1a; 解释&#xff1a;

MSPM0L1306时钟树

图显示了MSPM0Lxx系列设备的顶级时钟树。此图显示映射 振荡器&#xff08;源&#xff09;和时钟&#xff08;目的地&#xff09;之间&#xff0c;以及的SYSCTL寄存器位字段 选择多路复用器。请注意&#xff0c;并非所有设备都具有图所示的所有时钟系统功能。

【Linux】模拟实现一个简单的日志系统

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 如果文章对…

权限维持--小结

权限维持 windows 域环境 基于验证 DLL 加载-SSP 基于验证 DLL 加载-HOOK 基于机制账号启用-DSRM 基于用户属性修改-SID-history 基于登录进程劫持-Skeleton-Key 单机 基于用户-隐藏用户 基于服务 TGT-黄金白银票据 基于软件-GotoHTTP&RustDesk 自启动 粘滞键 …

RERCS系统开发实战案例-Part03 创建Web Dynpro对应的FPM Application

1、通过事务码SE80 资源浏览器创建 2、通过事务码FPM_WB在WEB端创建 3、创建FPM Application步骤 1&#xff09;选择&#xff1a;在业务实体上创建FPM应用程序的向导&#xff1b; 2&#xff09;配置&#xff1a;输入平面布置对象&#xff1b; 3&#xff09;单击 下一个&#…

美业SaaS收银系统拓客系统源码分享-预约管理功能的作用和重要性

美业收银管理系统对于美容、美发、医美行业的门店来说至关重要&#xff0c;它不仅可以帮助提高管理效率和降低成本&#xff0c;还可以改善客户体验并促进业务增长。 &#xff08;私信获取源码/演示视频&#xff09; ▶ 美业系统中的【预约管理】有多种作用&#xff0c;包括&…

业务架构的位置及关系

背景 我们已经了解了业务架构的核心元素组成&#xff0c;以及各个扩展元素&#xff0c;同时对各个元素的关系协同也有了一些了解&#xff0c;那么接下来&#xff0c;我们进一步在宏观层面来看业务架构与其他架构的关系。 企业架构 企业架构有多种理解&#xff0c;也有多种叫…

kotlin 中的数字

以下均来自官方文档&#xff1a; 一、整数类型 1、kotlin中内置的整数类型&#xff0c;有四种不同大小的类型&#xff1a; 类型存储大小&#xff08;比特数&#xff09;最小值最大值Byte8-128127Short16-3276832767Int32-2,147,483,648 (-231)2,147,483,647 (231 - 1)Long64…

(Git)多人协作1

文章目录 前言总结 前言 目标&#xff1a;master分支下file.txt文件新增“aaa”,“bbb” 实现&#xff1a;开发者1新增“aaa”,开发者2新增“bbb” 条件&#xff1a;在同一个分支下协作完成 实际开发过程中&#xff0c;每个用户都与属于自己的码云账户&#xff0c;如果想要进…