【背景描述】

传统用户名+密码+验证码的登录模式已经令人厌烦了,手机APP扫码登录才是顺应潮流,原本以为很复杂,查了一些资料,后来发现其实实现逻辑很简单,特此记录一下,以后可能会经常用到。

【实现方案】

 

1. PC端生成二维码

2. 用户使用手机app扫描二维码,跳转授权登录页面

3. 用户点击“确认登录”,后台插入记录

4.与此同时,PC端不断轮询后台接口check用户登陆已否

5.登录成功后,PC端跳转页面到主页,结束 

【准备工作】

安装二维码插件vue-qr:https://github.com/Binaryify/vue-qr#readme

【代码实现】

1. 在页面上引入vue-qr插件并完成注册

  import vueQR from 'vue-qr'
components: {
    'vue-qr': vueQR
},

2. 绘制二维码区域

 <div class="yzl-qrcode-tips">
    <vue-qr v-if="showQRCode" :text="QRCodeLoginUrl" :size="200" />
    <el-image
        v-else
        style="width: 200px; height: 200px"
        :src="img_src"
        fit="cover"
        @click="initYzlQRLoginCode"
     />
</div>
data () {
      return {
        // 二维码刷新图片
        img_src: require('../../assets/img/click_flush.png'),
        QRCodeLoginUrl: '', // 二维码url地址
        showQRCode: false, // 是否显示二维码
        timer: null, // 初始定时器变量名为null
        yzl_code: null // 判断用户扫码登录的UUID
      }
},

这里放置了两个控件,一个是用于渲染二维码的<vue-qr>,一个是用于二维码过期后提示用户点击刷新的图片。二维码不能一直展示给用户,需要设定一个过期时间,一般1分钟,提示用户重新点击获取新的二维码。

3. 页面初始化时便自动加载二维码

created () {
    // 初始化登录二维码
    this.initYzlQRLoginCode()
},
methods: {
    initYzlQRLoginCode () {
        const _this = this
        this.yzl_code = this.getUUID() // 获取一个随机ID用于登录用户标识
        const url = 'myappQRCodeGenerateAddress?sys_code=xxxx&yzl_code=' + this.yzl_code // 手机扫码后跳转地址
        getLoginQRCode(url).then(res => {
            this.QRCodeLoginUrl = res.qrcode // 二维码URL
            this.showQRCode = true
            // ==== 二维码获取成功 ====
            // 1.开启轮询接口判断用户是否已完成扫码登录
            _this.start()
            // 2. 开启1分钟倒计时
            setTimeout(function () {
              _this.QRCodeLoginUrl = ''
              _this.showQRCode = false
              _this.end() // 手动停止定时器
            }, 60000)
        })
    }
}

4. initYzlQRLoginCode

二维码实际上是一串手机app可识别的URL地址,当手机扫码后会跳转到一个页面去执行后续的操作,这个函数的目的就是为了获取二维码显示的URL地址。

这里是调用了一个api来获取具体的跳转地址,请注意实际情况会根据APP的不同而有所不同,重点在于需要生成一串手机app可识别的URL地址

需要注意到这个跳转地址携带了两个参数,sys_code用于区别登录系统,一般是固定的字符串,yzl_code则是用户登陆标识,是一串随机数,用户每刷新一次二维码,这个值也会跟着变化,不是固定的,有效期为1分钟。

5. 手机扫码后一般会出现一个用户授权登录页面

当用户点击确认登录以后,这里会调用一个后台接口,向数据库插入一条用户完成登录的记录,主要字段是sys_codeyzl_code,还要记录登录时间,判断是否过期

此时前端并没有闲着,当二维码生成以后,前端每隔一段时间就向后台发送一次请求,判断当前用户是否已完成扫码登录,这个过程也体现在initYzlQRLoginCode

initYzlQRLoginCode除了获取二维码,还干了两件事

1=>开启轮询接口判断用户

前端在生成二维码后就开启了轮询,每隔一段时间向后台发送请求,check当前用户是否已完成扫码登录,如果已经完成登录,会跳转到主页

2=>开启1分钟倒计时

将二维码屏蔽掉,换成提示用户点击刷新的图片,并手动停止定时器,停止轮询请求

// 1.开启轮询接口判断用户是否已完成扫码登录
_this.start()
// 2. 开启1分钟倒计时
setTimeout(function () {
    _this.QRCodeLoginUrl = ''
    _this.showQRCode = false
    _this.end() // 手动停止定时器
}, 60000)
start () {
    // 将定时器名字赋值到变量中
    this.timer = setInterval(() => {
    console.log('开始轮询接口----')
    const yzl_code = this.yzl_code
    checkUserLogin(yzl_code).then(res => {
        if (res.code === 200) { // 登录成功-200 | 登录失败-203
              this.end() // 停止轮询 
              this.$router.push('/home') // 跳转到主页
            }
          })
    }, 2000)
},
end () {
    clearInterval(this.timer)
    this.timer = null // 这里最好清除一下,回归默认值
    // 众所周知,定时器返回一个随机整数,用于表示定时器的编号,后面通过名字可以取消这个定时器的执行
    console.log('结束轮询接口----')
}

最后记得在页面销毁的时候定时器销毁 

beforeDestroy () {
    clearInterval(this.timer) // 清除定时器
}

【参考】

92行代码!!!解密哔哩哔哩扫码登陆【超级详细】_哔哩哔哩_bilibili

二维码扫码登录是什么原理

vue中使用setInterval()循环定时器的注意事项 - 知乎

vue页面的定时刷新setInterval()_u013158317的博客-CSDN博客_vue定时器定时刷新

Logo

前往低代码交流专区

更多推荐