🔥🔥 超实用,Vue实现微信扫码登录

9,420 阅读2分钟

小知识,大挑战!本文正在参与「程序员必备小知识」创作活动

本文已参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

前言

微信扫码登录是非常常见的需求,让微信用户使用微信登录第三方应用或网站,无非两种展现方式

  • 第一种,重定向到微信指定的扫码页面
  • 第二种,网站将微信登录二维码内嵌到页面中 该模式整体流程:
  1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据code参数;
  2. 通过code参数加上AppID和AppSecret等,通过API换取access_token;
  3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。 参数说明
参数是否必须说明
self_redirecttrue:手机点击确认登录后可以在 iframe 内跳转到 redirect_uri,false:手机点击确认登录后可以在 top window 跳转到 redirect_uri。默认为 false。
id第三方页面显示二维码的容器id
appid应用唯一标识,在微信开放平台提交应用审核通过后获得
scope应用授权作用域,拥有多个作用域用逗号(,)分隔,网页应用目前仅填写snsapi_login即可
redirect_uri重定向地址,需要进行UrlEncode
state用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加session进行校验
style提供"black"、"white"可选,默认为黑色文字描述。详见文档底部FAQ
href自定义样式链接,第三方可根据实际需求覆盖默认样式。详见文档底部FAQ

这里主要说的是第二种,将微信二维码内嵌到网站页面中,在网站内就能完成登录,无需跳转到微信域下登录后再返回,提升微信登录的流畅性与成功率。

这里使用vue-wxlogin,方便组件化模块化引入

npm install vue-wxlogin --save-dev

封装成组件

<template>
  <div class="wxLogin">
    <span class="title">微信扫一扫登录</span>
    <div class="main_wx">
      <wxlogin
        v-if="appid && redirect_uri"
        :appid="appid"
        scope="snsapi_login"
        :redirect_uri="redirect_uri"
        :href="href"
        :state="state"
      ></wxlogin>
    </div>
    <p>
      请使用微信扫描二维码登录
    </p>
  </div>
</template>

<script>
import wxlogin from 'vue-wxlogin'
import api from '@api/index'
export default {
  name: 'wxLogin',
  components: { wxlogin },
  data () {
    return {
      appid: '',
      redirect_uri: '',
      state: '1',
      href: '' // 自定义样式链接
    }
  },
  mounted () {
    this.getWeChatUrl()
  },
  methods: {
    // 获取微信appid和回调地址redirect_uri,指定内嵌的路由地址weChatLogin
    getWeChatUrl () {
      api.wachatQrUrl().then(res => {
        if (res && res.code === '0000') {
          const data = res.data
          this.appid = data.appId
          this.redirect_uri = data.wxCallbackUrl + 'weChatLogin'
        }
      })
    }
  }
}
</script>

在导航守卫router.beforeEach函数中进行拦截判断,获取url中的code,根据code调用接口进行登录验证

router.beforeEach((to, from, next) => {
  let code = null
  if (to.name === 'weChatLogin') {
    code = to.query.code || null
  }
  // 微信授权登陆
  if (code) {
    api.weChatOauth(code).then(res => {
      if (res?.code === '0000') {
        // 登录成功,并提示,跳转到用户主页面
        Message({
          type: 'success',
          message: '登录成功'
        })
        router.push({ path: '/index' })
      }
    })
  } else {
    next()
  }
})

最后

微信截图_20211008175145.png