手机号注册登录(保姆级)

简介: 在uni-app中,登录流程分为三个主要步骤:1) 发送登录请求至`/api/admin/loginUser`,检查返回的`code`是否为200;2) 如果`code`为200,将用户信息存入vuex并持久化到localStorage;3) 提供登录、注册及找回密码的界面元素,如表单验证、按钮点击事件处理,其中注册涉及验证码验证、新用户添加到数据库。登录成功后,用户信息会被用于后续的接口调用身份验证。

登录流程(uni-app)

@[toc]

1.登录实现

1.发送登录请求/api/admin/loginUser
2.判断返回的code是否200.
3.code200 则向vuex userLogin传递用户的信息。
4.并且做持久化存储。localStorage.setItem('userInfo',JSON.stringify(user))

image.png

<template>
    <view class="login">
        <view class="login-title">场馆预约</view>
        <view class="login-content">
            <el-form :model="form" :rules="rules" ref="form" label-width="40px" class="demo-ruleForm">
                <el-form-item prop="phone">
                    <el-input v-model="form.phone" placeholder="用户名/手机号"></el-input>
                </el-form-item>
                <el-form-item prop="password">
                    <el-input v-model="form.password" placeholder="密码" type="password"></el-input>
                </el-form-item>
            </el-form>
        </view>
        <view class="login-button"><el-button type="info" round @click="onsubmit">登录</el-button></view>
        <view class="login-botton">
            <view class="login-password" @click="findPassword">找回密码</view>
            <span>|</span>
            <view class="login-zhuce" @click="Registration">注册账号</view>
        </view>
    </view>
</template>

<script>
import {
   
    mapMutations } from 'vuex';
export default {
   
   
    data() {
   
   
        return {
   
   
            form: {
   
   
                phone: '',
                password: ''
            },
            rules: {
   
   
                phone: [{
   
    required: true, message: '请输入手机号', rule: '/^1[23456789]\d{9}$/' }],
                password: [{
   
    required: true, message: '请输入密码', trigger: 'blur' }]
            }
        };
    },
    methods: {
   
   
        // ...mapMutations(['user_Login']),
        //登录
        onsubmit() {
   
   
            this.$refs.form.validate(valid => {
   
   
                if (valid) {
   
   
                    uni.request({
   
   
                        url: '/api/admin/loginUser',
                        method: 'POST',
                        data: this.form,
                        success: res => {
   
   
                            console.log(res.data.data.data);
                            if (res.data.code == 200) {
   
   
                                this.$store.commit("userLogin",res.data.data.data );
                             //页面跳转
                                this.$router.push('/pages/my/my');

                                uni.showToast({
   
   
                                    title: res.data.data.msg,
                                    icon: 'none'
                             });
                            } else {
   
   
                                uni.showToast({
   
   
                                    title: res.data.data.msg,
                                    icon: 'none'
                                });
                            }
                        }
                    });
                } else {
   
   
                    console.log('error submit!!');
                    return false;
                }
            });
        },
        Registration() {
   
   
            console.log('hah ');
            uni.navigateTo({
   
   
                url: '../../pages/login/registration'
            });
        },
        findPassword() {
   
   
            console.log('hah ');
            this.$router.push('/pages/login/findPassword');
        }
    }
};
</script>

<style lang="less">
.login {
   
   
    .login-title {
   
   
        padding-top: 150rpx;
        display: flex;
        justify-content: center;
        font-weight: 700;
        font-size: 40rpx;
        letter-spacing: 5rpx;
        margin-bottom: 50rpx;
    }
    .demo-ruleForm {
   
   
        width: 90%;
        height: 60rpx;
    }
    /deep/.el-input__inner {
   
   
        height: 100rpx;
        border-radius: 50rpx;
        padding-left: 40rpx;
    }
    .login-botton {
   
   
    }
    /deep/.el-button--info {
   
   
        width: 80%;
        margin-left: 12%;
        margin-top: 260rpx;
        height: 80rpx;
    }
    .login-botton {
   
   
        display: flex;
        margin-top: 100rpx;
        justify-content: center;
        .login-password {
   
   
            padding-right: 20rpx;
            color: #2d66e3;
        }
        .login-zhuce {
   
   
            padding-left: 20rpx;
            color: #2d66e3;
        }
    }
}
</style>

==/api/admin/loginUser 服务端的代码==。

 // 普通用户登录数据
router.post('/loginUser', function(req, res, next) {
   
   

  let params={
   
   
     phone:req.body.phone,
     password:req.body.password
  }
 connection.query(user.queryUserTel(params),(err,results,fields)=>{
   
   
  //手机号存在
   if(results.length>0){
   
   
       connection.query(user.queryUserPwd(params),(err,results,fields)=>{
   
   
         if(results.length>0){
   
   
           //手机号和密码都对
           res.send({
   
   
            code:200,
            data:{
   
   
              success:true,
              msg:'登录成功',
              data:results[0]
            }
          })

         }else{
   
   
          //密码不对
          res.send({
   
   
            code:302,
            data:{
   
   
              success:false,
              msg:'密码不对'
            }
          })
         }
       })
   }else{
   
   
    //不存在,返回错误信息
    res.send({
   
   
      code:301,
      data:{
   
   
        success:false,
        msg:'手机号不存在'
      }
    })

   }
})
})

2.登录实现

1验证码时要判断用户输入的手机号是否满足要求。
2.若满足要求则向服务器发送 /api/admin/code
3.判断请求返回是否成功。
4.则返回用户手机的验证码

== 注册阶段==,则要判断用户输入的验证码与服务器返回的验证码是否相同。
2.如果验证码真确则,则需要判断用户是否已近存在 /api/admin/addUser。
3.若用用户存在则直接登录跳转。
4.若用户不存在则需要向数据中添加用户。

<template>
    <view class="registration">
       <view class="registration-content">
         <el-form  :rules="rules" ref="form" label-width="40px" class="demo-ruleForm">
             <el-form-item prop="phone">
                 <el-input v-model="phone" placeholder="手机号"></el-input>
             </el-form-item>
             <el-form-item prop="code" class='pwd'>
                 <el-input v-model="userCode" placeholder="验证码" type="password"></el-input>
                <el-button type="warning" :disabled='disabled' @click='sendCode'>{
   
   {
   
   codeMsg}}</el-button>
             </el-form-item>
         </el-form>
       </view>
       <view class="login-button"><el-button type="info" round @click="login">注册</el-button></view>
       <view class="registration-botton">
           <view class="registration-password" @click="goBack">密码登陆</view>
       </view>
    </view>
</template>

<script>
    export default {
   
   
        data() {
   
   
            return {
   
   
                phone:"",
                userCode:'',
                disabled:false,
                codeNum:10,
                codeMsg:'获取验证码',
                code:"",
                rules:{
   
   
                    phone:{
   
   
                        rule: '/^1[23456789]\d{9}$/',
                        meg:'手机的格式不对'
                    }
                }
            };
        },
        methods:{
   
   
            sendCode(){
   
   
            if (this.phone == '') {
   
   
                uni.showToast({
   
   
                    title: '手机号不能为空',
                    icon: 'none'
                });
            } else if (this.phone != '') {
   
   
                var reg = /^1[3456789]\d{9}$/;
                if (!reg.test(this.phone)) {
   
   
                    uni.showToast({
   
   
                        title: '输入有效的手机号',
                        icon: 'none'
                    });
                }else{
   
   
                    //禁用按钮
                    this.disabled=true

                    //发送请求
                    uni.request({
   
   
                        url:'/api/admin/code',
                        method:'POST',
                        data:{
   
   
                            phone:this.phone
                        },
                        success:res=>{
   
   
                            console.log('11',res.data.data)
                            if(res.data.data.success){
   
   
                                this.code=res.data.data.data
                            }
                        }
                    })
                    //倒计时
                    let timer=setInterval(()=>{
   
   
                        --this.codeNum;
                        this.codeMsg=`重新发送 ${
     
     this.codeNum}`
                    },1000)
                    //判断定时器停止
                    setTimeout(()=>{
   
   
                        clearInterval(timer);
                        this.disabled=false,
                        this.codeMsg='获取验证码',
                        this.codeNum=10
                    },10000)
                  }
                }
            },
            //登录
            login(){
   
   
                if(this.code==''|| this.phone==''){
   
   
                    uni.showToast({
   
   
                        title:'手机号不能为空',
                        icon:'none'
                    })
                }else if(this.userCode == this.code){
   
   
                    //验证码正确
                    uni.request({
   
   
                        url:'/api/admin/addUser',
                        method:'POST',
                        data:{
   
   
                            phone:this.phone
                        },
                        success:res=>{
   
   
                            //code 200 注册成功
                            if(res.data.code==200){
   
   
                                uni.showToast({
   
   
                                    title:res.data.data.msg,
                                    icon:'none'
                                })
                                //给vuex添加数据
                                this.$store.commit("userLogin",res.data.data.data );
                                //路由跳转
                                this.$router.push('/pages/my/my')
                            }else{
   
   
                                uni.showToast({
   
   
                                    title:res.data.data.msg,
                                    icon:'none'
                                })
                            }
                        }
                    })
                }
            },
            //密码登录
            goBack(){
   
   
              this.$router.push('/pages/login/login')
            },
            validate(key){
   
   
                let bool=true;
                if(!this.rules[key].rule.test(this[key])){
   
   
                    uni.showToast({
   
   
                        title:this.rules[key].meg,
                        icon:'none'
                    })
                    bool=false;
                    return false
                }
                return bool
            }
        }
    }
</script>

<style lang="less">
  .demo-ruleForm {
   
   
      width: 90%;
      height: 50rpx;
    padding-top: 100rpx;
  }
  /deep/.el-input__inner {
   
   
      height: 100rpx;
      border-radius: 5rpx;
      padding-left: 40rpx;
  }
  /deep/.el-form-item__content{
   
   
      display: flex;
  }
  /deep/.el-button--info {
   
   
      width: 80%;
      margin-left: 12%;
      margin-top: 260rpx;
      height: 80rpx;
  }
  .registration-botton {
   
   
      display: flex;
      margin-top: 50rpx;
      justify-content: space-between;
      .registration-password {
   
   
          padding-left: 40rpx;
          color: #2d66e3;
      }
      .registration-zhuce {
   
   
          padding-right: 40rpx;

          color: #2d66e3;
      }
  }
</style>

==服务端代码/api/admin/code,获取短信验证码==

//发送短信验吗
router.post('/code',function(req,res,next){
   
   
  let phone=req.body.phone
  //短信应用SDK
   var appid=1400187558;
   // appKey
   var appkey='填自己的';

   var phoneNumbers=[phone];

   var templatedId=舔自己的

   var smsSign='舔自己的’;

   var qcloudsms=QcloudSms(appid,appkey);

   function callback(err,ress,resData){
   
   
    if(err){
   
   
      console.log('err',err);
    }else{
   
   
      //返回给前端数据
      res.send({
   
   
        code:200,
        data:{
   
   
          success:true,
          data:ress.req.body.params[0]
        }
      })
    }
   }

   var ssender = qcloudsms.SmsSingleSender();
   //往上手机上发送的数据
   var params=[Math.floor(Math.random()*(9999-1000))+1000];
   ssender.sendWithParam(86,phoneNumbers[0],templatedId,
    params,smsSign,"","",callback);
})

==服务端代码/api/admin/addUser。==

//新增用户
router.post('/addUser',function(req,res,next){
   
   

  let tel={
   
   
    phone:req.body.phone
  }
  //查询用户是否存在
  connection.query(user.queryUserTel(tel),function(error,results){
   
   
    // if(error) throw error;
    if(results.length>0){
   
   
      //用户存在
      res.send({
   
   
        code:200,
        data:{
   
   
          success:true,
          msg:"登录成功",
          data:results[0]
        }
      })
    }else{
   
   
      //新增用户
      //引入token包
      let pwd=require('jsonwebtoken')
      //用户信息
      let payload={
   
   
        phone:req.body.phone
      }
      //口令
      let secret='xiaoming'
      //生成token
      let token =pwd.sign(payload,secret)
      var sql='insert into users values(null,?,?,?,?,?,?,?,?,?)'
      connection.query(sql,['小明',"666666",req.body.phone,"12","11","22",token,"0","0"],function(error,results){
   
   
        if(error){
   
   
          console.log('插入失败',error.message);
          return;
       }      
       console.log('插入成功:',results);     
        //查询用户
        connection.query(user.queryUserTel(tel),function(e,r){
   
   
          res.send({
   
   
            code:200,
            data:{
   
   
              success:true,
              msg:"登录成功",
              data:r[0]
            }
          })
        })
      })
    }
  })
})

3.找回密码

1.首先判断用户输入的手机号是否符合要求
2.若符合要求则向后端服务器发送器请求/api/admin/code获取验证码
3.若用户验证码填写正确。则需要跳转到下一步。

1.用户输入密码后,判断用户输入的密码是否符合要求。
2.若用户输入的密码符合要求则向服务端发送 /api/admin/updataUser,修改用户数据。
3.若修改用户数据成功,则返回成功信息。并且跳转到登录页面。

<template>
    <view class="registration">
        <view class="registration-content">
            <el-form :rules="rules" ref="form" label-width="40px" class="demo-ruleForm">
                <el-form-item prop="phone"><el-input v-model="phone" placeholder="手机号"></el-input></el-form-item>
                <el-form-item prop="code" class="pwd">
                    <el-input v-model="userCode" placeholder="验证码" type="password"></el-input>
                    <el-button type="warning" :disabled="disabled" @click="sendCode">{
   
   {
   
    codeMsg }}</el-button>
                </el-form-item>
            </el-form>
        </view>
        <view class="login-button"><el-button type="info" round @click="login">下一步</el-button></view>
    </view>
</template>

<script>
export default {
   
   
    data() {
   
   
        return {
   
   
            phone: '',
            userCode: '',
            disabled: false,
            codeNum: 10,
            codeMsg: '获取验证码',
            code: '',
            rules: {
   
   
                phone: {
   
   
                    rule: '/^1[23456789]\d{9}$/',
                    meg: '手机的格式不对'
                }
            }
        };
    },
    methods: {
   
   
        sendCode() {
   
   
            if (this.phone == '') {
   
   
                uni.showToast({
   
   
                    title: '手机号不能为空',
                    icon: 'none'
                });
            } else if (this.phone != '') {
   
   
                var reg = /^1[3456789]\d{9}$/;
                if (!reg.test(this.phone)) {
   
   
                    uni.showToast({
   
   
                        title: '输入有效的手机号',
                        icon: 'none'
                    });
                }else{
   
   
                    //禁用按钮
                    this.disabled = true;

                    //发送请求
                    uni.request({
   
   
                        url: '/api/admin/code',
                    method: 'POST',
                        data: {
   
   
                            phone: this.phone
                        },
                        success: res => {
   
   
                            console.log('11', res.data.data);
                            if (res.data.data.success) {
   
   
                                this.code = res.data.data.data;
                            }
                        }
                    });
                    //倒计时
                    let timer = setInterval(() => {
   
   
                        --this.codeNum;
                        this.codeMsg = `重新发送 ${
     
     this.codeNum}`;
                    }, 1000);
                    //判断定时器停止
                    setTimeout(() => {
   
   
                        clearInterval(timer);
                        (this.disabled = false), (this.codeMsg = '获取验证码'), (this.codeNum = 10);
                    }, 10000);
                }
            }
        },
        //登录
        login() {
   
   
            if(this.code==''|| this.phone==''){
   
   
                uni.showToast({
   
   
                    title:'手机号不能为空',
                    icon:'none'
                })
            }else if (this.userCode == this.code) {
   
   
                //验证码正确,查询数据库中是否有这个永辉
                uni.request({
   
   
                    url: '/api/admin/searchUser',
                    method: 'POST',
                    data: {
   
   
                        phone: this.phone
                    },
                    success: res => {
   
   
                        //code 200 用户存在
                        if(res.data.code==200){
   
   
                            this.$router.push('/pages/login/nextPassword?phone='+this.phone)
                        }else{
   
   
                           uni.showToast({
   
   
                               title:res.data.da.msg,
                            icon:'none'
                           })
                           return;
                        }
                    }
                });
            } else if (this.code != this.userCode) {
   
   
                uni.showToast({
   
   
                    title: '验证码不正确',
                    icon: 'none'
                });
            }
        },
        //密码登录
        goBack() {
   
   
            this.$router.push('/pages/login/login');
        }
    }
};
</script>

<style lang="less">
.demo-ruleForm {
   
   
    width: 90%;
    height: 50rpx;
    padding-top: 100rpx;
}
/deep/.el-input__inner {
   
   
    height: 100rpx;
    border-radius: 5rpx;
    padding-left: 40rpx;
}
/deep/.el-form-item__content {
   
   
    display: flex;
}
/deep/.el-button--info {
   
   
    width: 80%;
    margin-left: 12%;
    margin-top: 260rpx;
    height: 80rpx;
}
</style>

==服务端代码 /api/admin/updataUser==

//修改用户的密码
router.post('/updataUser',function(req,res,next){
   
   
  let params={
   
   
    userPwd:req.body.password,
    phone:req.body.phone
  }
 //查询手机号对应的id
 connection.query(user.queryUserTel(params),function(error,results){
   
   

  let id=results[0].id
  let pwd=results[0].password
  var sql='update users set password= '+params.userPwd+' where id='+id
  console.log(sql)
  connection.query(sql,function(error,results){
   
   
    res.send({
   
   
      code:200,
      data:{
   
   
        success:true,
        msg:'修改成功'
      }
    })
  })

 })


})

4.token

token使用方法

token的使用流程如下:
(1)用户发起请求,提交用户名和密码;
(2)服务器验证用户名和密码;
(3)服务器生成token,返回给客户端;
(4)客户端拿着token,将token作为参数,发起请求;
(5)服务器验证token,通过验证后返回请求数据,并且更新token;
(6)客户端拿到更新的token,未来的请求都携带最新的token,从而实现无状态的身份验证

1.1 node环境配置token

npm install jsonwebtoken

2.2 生成token

//引入token包
      let pwd=require('jsonwebtoken')
      //用户信息
      let payload={
   
   
        phone:req.body.phone
      }
      //口令
      let secret='xiaoming'
      //生成token
      let token =pwd.sign(payload,secret)
目录
相关文章
|
29天前
|
Android开发 数据安全/隐私保护 虚拟化
安卓手机远程连接登录Windows服务器教程
安卓手机远程连接登录Windows服务器教程
56 4
|
2月前
Discuz! X3.5插件云诺-阿里云短信手机登录 会员登录后也无法查看附件图片的问题解决方法
Discuz! X3.5插件云诺-阿里云短信手机登录 会员登录后也无法查看附件图片的问题解决方法
38 2
|
4月前
|
小程序 安全 Java
|
4月前
【Azure 环境】中国区Azure B2C 是否支持手机验证码登录呢?
【Azure 环境】中国区Azure B2C 是否支持手机验证码登录呢?
|
4月前
|
Java Android开发 UED
安卓scheme_url调端:如果手机上多个app都注册了 http或者https 的 intent。 调端的时候,调起哪个app呢?
当多个Android应用注册了相同的URL Scheme(如http或https)时,系统会在尝试打开这类链接时展示一个选择对话框,让用户挑选偏好应用。若用户选择“始终”使用某个应用,则后续相同链接将直接由该应用处理,无需再次选择。本文以App A与App B为例,展示了如何在`AndroidManifest.xml`中配置对http与https的支持,并提供了从其他应用发起调用的示例代码。此外,还讨论了如何在系统设置中管理这些默认应用选择,以及建议开发者为避免冲突应注册更独特的Scheme。
|
6月前
|
小程序 前端开发 Java
(JAVA)支付宝小程序登录相关(authToken获取用户唯一userId、encryptedData解密手机号)
(JAVA)支付宝小程序登录相关(authToken获取用户唯一userId、encryptedData解密手机号)
456 0
|
7月前
|
安全 Linux 网络安全
购了轻服务器,手机登录服务器用root和administrator做登录名,都提示别名已存在,请修改
【2月更文挑战第16天】购了轻服务器,手机登录服务器用root和administrator做登录名,都提示别名已存在,请修改
53 1
|
7月前
|
安全 Linux 网络安全
手机登录服务器用root和administrator做登录名,都提示别名已存在
【2月更文挑战第5天】手机登录服务器用root和administrator做登录名,都提示别名已存在
71 8
|
7月前
|
JSON 前端开发 安全
前后端分离项目知识汇总(微信扫码登录,手机验证码登录,JWT)-2
前后端分离项目知识汇总(微信扫码登录,手机验证码登录,JWT)
124 0
|
6月前
|
网络协议 Android开发 数据安全/隐私保护
Android手机上使用Socks5全局代理-教程+软件
Android手机上使用Socks5全局代理-教程+软件
5034 2