[记录]vue3实现PC项目微信扫码进行账号注册/登录(内嵌二维码) 您所在的位置:网站首页 怎么扫二维码登录微信 [记录]vue3实现PC项目微信扫码进行账号注册/登录(内嵌二维码)

[记录]vue3实现PC项目微信扫码进行账号注册/登录(内嵌二维码)

2024-07-16 22:48| 来源: 网络整理| 查看: 265

记录 "PC端采用微信扫码,进行账号注册/登录功能" 的实现过程(仅前端)

使用场景:在网站顶部导航栏的登录入口,中实现微信扫码登录功能

开发参考文档:微信官方文档(微信登录功能-网站应用微信登录开发指南)

微信提供的扫码方式有两种,分别是:

跳转二维码扫描页面内嵌式二维码(本记录选用的扫码方式)

根据文档我们可以知道关于扫码授权的模式整体流程为:

1. 第三方发起微信授权登录请求,微信用户允许授权第三方应用后,微信会拉起应用或重定向到第三方网站,并且带上授权临时票据 code 参数;

2. 通过 code 参数加上 AppID 和AppSecret等,通过 API 换取access_token;

3. 通过access_token进行接口调用,获取用户基本数据资源或帮助用户实现基本操作。

通过 微信开放平台 申请账号拿到appId和appSecret

页面中先引入如下 JS 文件,若网站不支持https可把前缀改为http

创建登录组件:login.vue

... import { reactive, watch, toRefs, getCurrentInstance, } from 'vue' export default { props: {}, setup(props, context) { const { appContext } = getCurrentInstance() const { $http } = appContext.config.globalProperties const state = reactive({ showQR: true, loginType: 'QRcode', showReg: false, showLogin: true, }) watch( () => state.loginType, newVal=> { state.showLogin = false state.showQR = false state.showReg = false switch(newVal){ case 'QRcode': state.showQR = true break; case 'register': state.showReg = true break; default: state.showLogin = true } } ) // 微信登录 const wechatLogin = async () => { // 从后端获取appid以及重定向地址 let { data, status } = await $http.get('XXX') if (!status == 200) return // 官方文档提供的实例对象,具体参数说明可往下看 let state = parseInt(new Date().getTime() / 1000) let obj = new WxLogin({ self_redirect: false, id: 'login_container', appid: data.appid, scope: 'snsapi_login', redirect_uri: data.redirect_url, // 这里跳的是扫码成功后,账户操作的地址 state: state, style: 'black', href: '', }) // 自己封装的sessionStorage方法 sessionStorage.setItem('beforeLogin', window.location.href) // 记录当前操作页面,以备后面跳转 sessionStorage.setItem('QRcode', 'login') // 记录当前扫码是注册还是登录 state.loginType = 'QRcode' } return { ...toRefs(state), wechatLogin } } }

扫码成功后,将会自动跳转到自定义的重定向地址,并能在地址上看到我们的code

https://www.xxx.com?code=0719adHa1IuEpD0NHCHa1MQtv30&state=1655733828

接着,我们就可以根据code,用文档给出的API,获取所需的数据

https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code

API相关参数说明

 返回样例:

// 正确返回样例 { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } // 错误返回样例 {"errcode":40029,"errmsg":"invalid code"}

 正确的返回参数说明:

在本项目我们获取code后,我们需要通过code去判断这个微信是否已经绑定账号,我们定向到操作页面,把code交给后端判断此code是否已绑定账户,并根据判断结果进行不同操作:

... 绑定账号 操作成功,正在跳转,请稍等 import { reactive, toRefs, getCurrentInstance } from 'vue' export default { components: {}, setup(props, context) { const { appContext } = getCurrentInstance() const { $g, $router, $http, $message } = appContext.config.globalProperties const state = reactive({ unionid: null, isLogin: sessionStorage.getItem('QRcode') == 'login', hasBind: false }) // 设置用户登录信息 const setInfo = (data, duration = 3000) => { let temp = data.user ... sessionStorage.removeItem('QRcode') // 移除QRcode标志 } // 跳转登录页面 const backPage = () => { const beforeLogin = sessionStorage.getItem('beforeLogin') sessionStorage.removeItem('beforeLogin') window.location.replace(beforeLogin) } // 第一次微信快捷登录,创建并绑定手机账号 const wxL = async () => { if (!state.unionid) return $message.warning('扫码失效,请重新扫码登录') let { data, status } = await $http.post('xxxxx', { unionid: state.unionid, ... }) if (status != 200) return setInfo(data) $message({ message: '登录绑定成功,正在跳转,请稍等', type: 'success', duration: 1000, onClose: () => { backPage() } }) } // 已有账号绑定微信 const wxB = async () => { let { data, status } = await $http.post('xxxx', { unionid: state.unionid, ... }) if (status != 200) return setInfo(data) $message({ message: '绑定成功,正在跳转,请稍等', type: 'success', duration: 1000, onClose: () => { backPage() } }) } // 获取unionid const getUnionid = async () => { let { data, status } = await $http.get('xxx', { code: $router.currentRoute.value.query.code }) if (status != 200) return // 从未绑定 if (!data.state) { state.unionid = data.unionid if (state.isLogin) return return wxB() //已有账号绑定微信 } state.hasBind = true setInfo(data) $message({ message: '登录成功,正在跳转,请稍等', type: 'success', duration: 1000, onClose: () => { backPage() } }) } getUnionid() return { ...toRefs(state), setInfo, backPage, getUnionid, wxL, wxB } } }


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有