思路
● 第一步是浏览器的逻辑
首先打开网页的时候,向服务器发送二维码登录的请求,服务器收到后会返回随机生成的uuid,把这uuid的key值存入redis中,一般设置60s作为过期时间。二维码过期之后,点击之后再次请求。(思路1:是后端可以直接返回二维码图片。思路2可以 前端生成二维码,获取到后可以进行赋值。)浏览器获得uuid之后,携带uuid向服务端请求是否可以登录。(这一步要进行轮询操作)
● 第二步是手机端逻辑
用户打开手机扫码后就得到uuid(必须是在登录状态下)在扫码之后跳转到一个新的页面 点击同意登录后。携带token和uuid 到服务端进行验证。如果验证成功向浏览器端返回成功信息。在浏览器端收到服务端传来的结果(结果里包含token)根据token进行用户登录。
核心代码
浏览器端
<template>
<view class="content">
<!-- 登录区域 -->
<view class="stylepos">
<view class="login-box">
<!-- 左边扫码登录区域 -->
<view class="left-scan">
<text class="title">打开您的扫一扫</text>
<uqrcode ref="uqrcode" v-show="nopastCode" :size="220" canvas-id="qrcode" :value="qrcodeValue"
:options="{ margin: 20 }" @click="clickQrcode"></uqrcode>
<image @click="refreshCode" v-show="pastCode" src="../../static/prstCode.png"
style="height:220px;width:220px"></image>
<text class="title">扫码登录</text>
</view>
<!-- 右边手输登录区域 -->
// <view>...</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
versionNo: '',
qrcodeValue: "1", // 二维码内容
isAgree: true, // 是否勾选服务条款,
nopastCode: true, //未过期二维码
pastCode: false, //过期二维码
timer: null, //定时器
timers: null, //定时器
}
},
mounted() {
this.getCode();
},
onHide() {
clearInterval(this.timers);
},
methods: {
//获取登录二维码
getCode() {
clearInterval(this.timer);
scanGetCode({ role: "STORE" }).then(res => {
if (res.data.code == 200) {
this.qrcodeValue = res.data.result
this.$refs.uqrcode.remake();
this.getStatus();
console.log(this.qrcodeValue);
this.timer = setInterval(() => {
clearInterval(this.timer);
clearInterval(this.timers);
this.pastCOdeIsno();
this.qrcodeValue = '';
}, 60000);
}
})
},
//刷新二维码
refreshCode() {
this.pastCOdeIsno();
this.getCode();
clearInterval(this.timers);
},
//二维码过期
pastCOdeIsno() {
this.nopastCode = !this.nopastCode;
this.pastCode = !this.pastCode;
},
//询问后端是否登录成功
getStatus() {
let _this = this;
if (this.qrcodeValue) {
isLogin({
uuid: this.qrcodeValue,
role: "STORE"
}).then(res => {
if (res.data.code == 200 && res.data.result) {
clearInterval(this.timers);
uni.showToast({
title: "登录成功",
duration: 1000
})
uni.setStorageSync('deviceId', this.deviceId);
storage.setAccessToken(res.data.result)
this.$EventBus.$emit('syncCashe');
uni.navigateTo({
url: "/pages/index/index"
})
} else {
_this.timers = setTimeout(function () {
_this.getStatus();
}, 1000);
}
})
} else {
clearInterval(this.timers);
}
},
// 点击二维码回调(刷新二维码)
clickQrcode() {
this.getCode();
},
}
}
</script>
移动端
<template>
<view class="back">
<view class="head">
<view>
<image class="img" src="../../../static/login.png" />
</view>
<view class="context">
<view class="txtone">
<text class="text">
即将登录您的账号
</text>
</view>
<view class="txttwo">
<text class="text">
请确认是否是本人登录
</text>
</view>
</view>
</view>
<view class="body">
<view class="loginbtn" @click="login">
<text class="logintext">
确认登录
</text>
</view>
<view class="cancelbtn" @click="cancel">
<text class="canceltext">
取消
</text>
</view>
</view>
</view>
</template>
<script>
import { getmobileScan } from '@/api/store.js';
export default {
data() {
return {
code: ''
};
},
onLoad(e) {
this.code = e.code;
},
methods: {
//登录
login() {
getmobileScan({ uuid: this.code }).then(res => {
if (res.data.code == 200 && res.data.message == "success") {
uni.showToast({
title: "授权登录成功",
icon: 'none'
})
uni.switchTab({
url: '/pages/tabbar/home/index'
});
}
})
},
//取消
cancel() {
uni.switchTab({
url: '/pages/tabbar/home/index'
});
}
}
};
</script>
总结
扫码登录的功能听起来很牛逼,了解思路做过之后发现其实也很简单。但凡时间都要去做,做过之后才会有收获。