登录流程(uni-app)
@[toc]
1.登录实现
1.发送登录请求/api/admin/loginUser
2.判断返回的code是否200.
3.code200 则向vuex userLogin传递用户的信息。
4.并且做持久化存储。localStorage.setItem('userInfo',JSON.stringify(user))
<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的使用流程如下:
(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)