• 抖音实战~手机号验证码一键注册登录流程(限制手机终端登录)


    在这里插入图片描述

    在这里插入图片描述

    一、手机号+验证码

    在这里插入图片描述

    二、前端
    2.1. 点击登陆流程
    • 1.先校验手机号是否合法?不合法,则提示“请输入正确的手机号”
    • 2.再校验是否勾选隐私协议,未勾选,则提示“请先同意《隐私及服务协议》”
    • 3.校验通过后,根据选择的登录类型进行判断,最后,则调用后端手机号验证码登录接口
    • 4.后端返回结果
      • 4.1.成功,则保存用户信息+token信息
      • 4.2.失败:则提示后端返回的提示语
    2.2. 点击登录源码
    			loginOrRegist() {
    				var me = this;
    				var mobile = me.mobile;
    				// 提交前,手机号校验
    				var reg = /^1[0-9]{10,10}$/;
    				if (!mobile || !reg.test(mobile)) {
    					uni.showToast({
    						title: '请输入正确的手机号',
    						icon: 'none'
    					})
    					return
    				}
    
    				if (!this.agree) {
    					uni.showToast({
    						title: '请先同意《隐私及服务协议》',
    						icon: 'none'
    					});
    					return;
    				}
    				var serverUrl = app.globalData.serverUrl;
    
    				// 手机号密码~登录/注册
    				if (!this.logintype) {
    					var password = me.password;
    
    					if (app.isStrEmpty(password)) {
    						uni.showToast({
    							title: "密码不能为空",
    							icon: "none"
    						});
    						return;
    					}
    
    					// uni.showLoading()
    					// 调用后端登录注册
    					uni.request({
    						method: "POST",
    						url: serverUrl + "/user/mobileAndPasswordRegistLogin",
    						data: {
    							"mobile": mobile,
    							"password": password
    						},
    						success(result) {
    							var status = result.data.status;
    							// uni.hideLoading();
    							if (status == 200) {
    								var userInfo = result.data.data;
    								console.log("密码->userInfo", userInfo)
    
    								app.setUserInfoSession(userInfo);
    								app.setUserSessionToken(userInfo.userToken);
    								// 登录成功,关闭当前页
    								// me.close();
    								uni.reLaunch({
    									url: "../me/me"
    								})
    							} else if (status != 200) {
    								uni.showToast({
    									title: result.data.msg,
    									icon: "none",
    									duration: 3000
    								});
    							}
    						}
    					});
    				}
    
    				// 手机号验证码~登录/注册
    				if (this.logintype) {
    					var verifyCode = me.verifyCode;
    					console.log("verifyCode", verifyCode)
    					if (app.isStrEmpty(verifyCode)) {
    						uni.showToast({
    							title: "请填写验证码",
    							icon: "none"
    						});
    						return;
    					}
    
    					// 调用后端登录注册
    					uni.request({
    						method: "POST",
    						url: serverUrl + "/user/login",
    						data: {
    							"mobile": mobile,
    							"smsCode": verifyCode
    						},
    						success(result) {
    							var status = result.data.status;
    							// uni.hideLoading();
    							if (status == 200) {
    								var userInfo = result.data.data;
    								console.log("验证码->userInfo", userInfo)
    
    								app.setUserInfoSession(userInfo);
    								app.setUserSessionToken(userInfo.userToken);
    								// 登录成功,关闭当前页
    								// me.close();
    								uni.reLaunch({
    									url: "../me/me"
    								})
    							} else if (status != 200) {
    								uni.showToast({
    									title: result.data.msg,
    									icon: "none",
    									duration: 3000
    								});
    							}
    						}
    					});
    				}
    			}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    三、后端登录
    3.1. 登录流程图

    会话拦截限制一台手机登录(流程图)
    在这里插入图片描述

    3.2. 流程简述
    • 1.前端传递userId和token
    • 2.后端接收userId和token
    • 3.校验userId和token是否为空
    • 4.校验任一为空,则提示“请登录后再继续操作!”
    • 5.不为空,通过UserId从redis中获取token
    • 6.redis中的token与传参token校验是否一致
    • 7.不一致,第一台登录的会“会话失效,请重新登录!”
    • 8.一致继续操作

    备注:由于登录不拦截,因此当第二台手机登录时,token会将第一台手机的登录token进行覆盖

    在这里插入图片描述
    在这里插入图片描述

    3.3. 手机号验证码登录流程
    • 1.从redis中获得验证码进行校验是否匹配
    • 2.查询数据库,判断用户是否存在
      • 2.1 如果用户为空,表示没有注册过,则为null,需要注册信息入库
      • 2.2 如果用户不为空,表示已经注册过,继续
    • 3.如果不为空,可以继续下方业务,可以保存用户会话信息
    • 4.用户登录注册成功以后,删除redis中的短信验证码
    • 5.返回用户信息,包含token令牌
        @PostMapping("login")
        public GraceJSONResult login(@Valid @RequestBody RegistLoginBO registLoginBO,
                                     HttpServletRequest request) throws Exception {
    
            String mobile = registLoginBO.getMobile();
            String code = registLoginBO.getSmsCode();
    
            // 1. 从redis中获得验证码进行校验是否匹配
            String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
            if (StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)) {
                return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
            }
    
            // 2. 查询数据库,判断用户是否存在
            Users user = userService.queryMobileIsExist(mobile);
            if (user == null) {
                // 2.1 如果用户为空,表示没有注册过,则为null,需要注册信息入库
                user = userService.createUser(mobile);
            }
    
            // 3. 如果不为空,可以继续下方业务,可以保存用户会话信息
            String uToken = UUID.randomUUID().toString();
            redis.set(REDIS_USER_TOKEN + ":" + user.getId(), uToken);
    
            // 4. 用户登录注册成功以后,删除redis中的短信验证码
            redis.del(MOBILE_SMSCODE + ":" + mobile);
    
            // 5. 返回用户信息,包含token令牌
            UsersVO usersVO = new UsersVO();
            BeanUtils.copyProperties(user, usersVO);
            usersVO.setUserToken(uToken);
            return GraceJSONResult.ok(usersVO);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
  • 相关阅读:
    CentOS7安装部署Nacos
    3天3定制大屏,反向PUA
    【工具篇】SQLite本地数据库在Unity3D的应用
    【初学者入门C语言】之运算符及表达式(二)
    【06】基础知识:React组件实例三大核心属性 - ref
    React组件应用于Spring MVC工程
    DC-7 靶机
    数组扁平化的方法
    Debian11系统简单配置
    C语言中typedef和define对比分析
  • 原文地址:https://blog.csdn.net/weixin_40816738/article/details/125343635