vue实现微信授权
1.首先安装weixin-js-sdk
npm install weixin-js-sdk
2.新建helper.js
//用于获取当前页面地址
export const getFullPath = (route) => {
return location.origin + route.fullPath.substr(1)
}
/**
* 修改 Route query 数据
* @param {Object} route
* @param {(Object|null)} [query=null]
* @return {Object}
*/
export const editRouteQuery = (route, query = null) => {
const _old = route.query
let _new = query
if (query) {
_new = Object.assign({}, _old, query)
}
for (let key in _new) {
if (!_new[key]) {
delete _new[key]
}
}
return {
...route,
query: _new,
}
}
3.新建wechatAuth.js 用于设置微信JSSDK
// import Vue from 'vue'
import wx from 'weixin-js-sdk'
import store from '@/store'
import { wechatJSSDK } from '@/api/permission'
/**
* 微信 JS-SDK 授权
*/
export const wechatAuth = async (url) => {
const wechatJSSDKData = await wechatJSSDK({ callBackUrl: url })
// if (wechatJSSDKData.error) {
// Vue.prototype.$toast('微信授权失败')
// }
const data = wechatJSSDKData.success || {}
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: data.appId, // 必填,公众号的唯一标识
timestamp: data.timestamp, // 必填,生成签名的时间戳
nonceStr: data.nonceStr, // 必填,生成签名的随机串
signature: data.signature, // 必填,签名
jsApiList: ['scanQRCode'], // 必填,需要使用的JS接口列表
})
wx.error(() => {
store.commit('system/setWechatReady', false)
})
wx.ready(() => {
store.commit('system/setWechatReady', true)
})
}
4.在router下的index.js做如下拦截
import Vue from 'vue'
import VueRouter from 'vue-router'
import store from '@/store'
import { getAuthUrl, getUserInfo, login } from '@/api/permission'
import { editRouteQuery, getFullPath } from '@/lib/helper'
import { reloadPage } from '@/utils/actions/router'
import { wechatAuth } from '@/utils/sdk/wechatJSSDK'
Vue.use(VueRouter)
const routes = [
...home,
]
const baseUrl = process.env.BASE_URL
const router = new VueRouter({
mode: 'history',
base: baseUrl,
routes,
})
router.beforeEach(async (to, from, next) => {
const code = to.query.code
const redirect = to.query.redirect
// 空白页放过
if (to.name === 'Blank') {
return next()
}
// 没有登录态也没有授权码,进行授权
// 可以认为只会出现在少数几个允许不登录访问的页面中
if (!store.getters['user/isLogin'] && !code) {
const result = await getAuthUrl({ callBackUrl: getFullPath(to) })
if (result.error) {
// TODO 降级处理
await Vue.prototype.$dialog.alert({
className: 'dialog-alert',
title: '提示',
message: '请求失败:1',
confirmButtonText: '刷新',
})
await reloadPage()
return next(false)
}
// 跳走要求授权
return (location.href = result.success.authorizedUrl)
}
// 存在授权 code 但是没有 token
if (!store.getters['user/isLogin'] && code) {
const result = await login({ roleType: 2, code })
if (result.error) {
// TODO 降级处理
await Vue.prototype.$dialog.alert({
className: 'dialog-alert',
title: '提示',
message: '请求失败:2',
confirmButtonText: '刷新',
})
await reloadPage()
return next(false)
}
// 保持登录态
store.commit('user/setToken', result.success.token)
// 移除 code 信息
await router.replace(editRouteQuery(to, { code: null, state: null }))
}
// 获得用户身份信息
// 仅在获得了 token 后请求,因为某些页面允许不登录访问
if (store.getters['user/isLogin'] && store.state.user.userInfo.notInit) {
const result = await getUserInfo()
if (result.error) {
// TODO 降级处理
await Vue.prototype.$dialog.alert({
className: 'dialog-alert',
title: '提示',
message: '请求失败:3',
confirmButtonText: '刷新',
})
await reloadPage()
return next(false)
}
// 存储用户信息
if (result.success) {
store.commit('user/setUserInfo', result.success)
} else {
store.commit('user/resetUserInfo')
}
}
if (redirect) {
next(redirect)
} else {
next()
}
})
router.afterEach(async (to) => {
// 空白页不做任何事
if (to.name === 'Blank') {
return
}
// 设置 title
document.title = title
const wechatUrl = getFullPath(to)
if (store.state.system.iOS) {
// iOS
if (window.entryUrl == '' || window.entryUrl == undefined) {
window.entryUrl = wechatUrl // 将后面的参数去除
}
await wechatAuth(window.entryUrl)
} else {
// 安卓
setTimeout(async () => {
await wechatAuth(wechatUrl)
}, 500)
}
})
export default router