【vue】使用手机app扫描二维码登录

【背景描述】

传统用户名+密码+验证码的登录模式已经令人厌烦了,手机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定时器定时刷新

  • 4
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要实现钉钉扫描二维码登录,需要进行以下步骤: 1. 在钉钉开放平台注册应用,并获取到应用的 `AppId` 和 `AppSecret`。 2. 在前端页面上实现钉钉扫描二维码的功能,可以使用钉钉提供的 `DingTalkPC.runtime.permission.requestAuthCode` 方法,该方法会弹出钉钉扫描二维码的界面,用户扫描二维码后会返回一个 `code` 值。 3. 前端将 `code` 值发送到后端,后端拿到 `code` 值以及 `AppId` 和 `AppSecret`,调用钉钉开放平台提供的接口获取用户的身份信息。 4. 后端将获取到的用户身份信息返回给前端,前端根据身份信息进行相应的页面跳转或者其他操作。 下面是一个简单的实现示例: 前端代码: ``` html <!-- 钉钉扫描二维码的按钮 --> <button @click="requestAuthCode">钉钉扫描二维码登录</button> <script> export default { methods: { requestAuthCode() { // 调用DingTalkPC.runtime.permission.requestAuthCode方法 DingTalkPC.runtime.permission.requestAuthCode({ corpId: '钉钉应用的CorpId', onSuccess: function(result) { // result.code为获取到的code值 // 将code值发送到后端进行身份验证 }, onFail: function(err) { console.log(err) } }); } } } </script> ``` 后端代码: ``` javascript const axios = require('axios'); // 获取用户身份信息的接口 const API_URL = 'https://oapi.dingtalk.com/sns/getuserinfo_bycode'; async function getUserInfo(code, appId, appSecret) { const url = `${API_URL}?accessKey=${appId}&accessSecret=${appSecret}&code=${code}`; const response = await axios.get(url); return response.data; } // 在路由中处理钉钉扫描二维码的请求 app.get('/dingtalk/login', async (req, res) => { const { code } = req.query; const appId = '你的应用AppId'; const appSecret = '你的应用AppSecret'; try { const userInfo = await getUserInfo(code, appId, appSecret); // 将获取到的用户身份信息返回给前端 res.send(userInfo); } catch (err) { console.log(err); res.status(500).send('获取用户信息失败'); } }); ``` 需要注意的是,以上代码仅为参考示例,实际应用中还需要考虑一些安全性和错误处理的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值