vue 微信网页授权,基于 vue-cli3.0+webpack 4+vant ui + sass+ rem 适配方案 +axios,开发的微信授权方案。项目地址:vue-wechat-auth
又又又一次来写微信网页授权,一年前写过的 [vue 微信授权解决方案]。
参考了[vue-wechat-login],思路有些不同,本文基于进入所有页面都必须先授权的操作。
与之前写的授权不同之处
这次的逻辑全部在 router 的 beforeEach 进行,相较更加简洁明。之前是在一个中间页 author.vue 中,加上微信授权要跳转很多次
在这里你能找到
- 微信网页授权前端解决方案,官方文档
- 如何使用 Natapp(ngrok)进行微信本地开发调试, 官方文档
- 如何配置微信开发测试账号
关于测试账号和本地开发设置
由于文章过长这里 [微信测试账号和本地开发调试] 记得回来哦~
微信网页授权
都设置好了那就开始微信网页开发第一步也是最重要的一步,微信网页授权
关于授权你首先要清楚的是,服务端要用到的是微信 openid 还是微信 unionid,这两者的区别是,如果你要的是 unionid, 那么你需要在 [微信开放平台] 去绑定测试账号。测试号的 appId 和 appsecret 在 微信公众平台 的测试号里找。微信公众号后台 -> 开发者工具 -> 公众平台测试帐号 -> 进入
如果你不需要 unionid,那这个你就可以省略,如果服务端是需要 unionid 的那不绑定的话授权会把报错的。记得问一下服务端开发人员哦。
开发
首先我们看下微信授权的流程图,关于微信网页授权
前端需要做的是
第一步:用户同意授权,获取 code,拼接微信授权地址,redirect_uri 就是你的当前地址,关于 appid 有些人是通过接口获取的,我这里就直接写在项目全局变量里了 VUE_APP_WECHAT_APPID,用户授权成功后微信会携带 code 和 status 跳回来
https://open.weixin.qq.com/connect/oauth2/authorize?appid=${this.appid}&redirect_uri=${this.redirect_uri}&response_type=code&scope=${this.scope}&state=${this.state}#wechat_redirect
第二步,访问登录接口,将 code 传给服务端,小哥哥进行一系列的操作,通过 code 换取网页授权 access_token,拉取用户信息(需 scope 为 snsapi_userinfo),返回是否登录成功,成功后返回用户信息和登录令牌 token
在 permission.js 中路由拦截进行这一系列操作,代码注释很详细了
permission.js
import router from './router'
import store from './store'
import getPageTitle from '@/utils/get-page-title'
import wechatAuth from './plugins/wechatAuth' // 微信登录插件
const qs = require('qs')
router.beforeEach((to, from, next) => {const loginStatus = Number(store.getters.loginStatus)
console.log('loginStatus=' + loginStatus)
console.log('token=' + store.getters.token)
// 页面标题
document.title = getPageTitle(to.meta.title)
if (loginStatus === 0) {
// 微信未授权登录跳转到授权登录页面
const url = window.location.href
// 解决重复登录 url 添加重复的 code 与 state 问题
const parseUrl = qs.parse(url.split('?')[1])
let loginUrl
if (parseUrl.code && parseUrl.state) {
delete parseUrl.code
delete parseUrl.state
loginUrl = `${url.split('?')[0]}?${qs.stringify(parseUrl)}`
} else {loginUrl = url}
// 设置微信授权回调地址
wechatAuth.redirect_uri = loginUrl
// 无论拒绝还是授权都设置成 1
store.dispatch('user/setLoginStatus', 1)
// 跳转到微信授权页面
window.location.href = wechatAuth.authUrl
} else if (loginStatus === 1) {
// 用户已授权,获取 code
try {
// 通过回调链接设置 code status
wechatAuth.returnFromWechat(to.fullPath)
} catch (err) {
// 失败,设置状态未登录,刷新页面
store.dispatch('user/setLoginStatus', 0)
location.reload()}
// 同意授权 to.fullPath 携带 code 参数,拒绝授权没有 code 参数
const code = wechatAuth.code
if (code) {
// 拿到 code 访问服务端的登录接口
store
.dispatch('user/loginWechatAuth', code)
.then(res => {
// 成功设置已登录状态
store.dispatch('user/setLoginStatus', 2)
next()})
.catch(() => {
// 失败,设置状态未登录,刷新页面
store.dispatch('user/setLoginStatus', 0)
location.reload()})
} else {store.dispatch('user/setLoginStatus', 0)
location.reload()}
} else {
// 已登录直接进入
next()}
})
登录成功后存用户信息,token。访问所有的接口的时候都会在 header 携带 token,如果 token 失效了,服务端会返回 401,做退出操作,删除登录状态,用户信息,token,刷新页面重新进入。
request.js
// 登录超时, 重新登录
if (res.status === 401) {store.dispatch('user/fedLogOut').then(() => {location.reload()
})
}
用户登录后将 token 和用户信息存入 storage 中,登录状态设置到 cookie 里,store user 中主要是进行用户信息存贮获取删除的操作
store/modules/user.js
import {loginByCode} from '@/api/user'
import {
saveToken,
saveLoginStatus,
saveUserInfo,
removeToken,
removeUserInfo,
removeLoginStatus,
loadLoginStatus,
loadToken,
loadUserInfo
} from '@/utils/cache'
const state = {loginStatus: loadLoginStatus(), // 登录状态
token: loadToken(), // token
userInfo: loadUserInfo() // 用户登录信息}
const mutations = {SET_USERINFO: (state, userInfo) => {state.userInfo = userInfo},
SET_LOGIN_STATUS: (state, loginStatus) => {state.loginStatus = loginStatus},
SET_TOKEN: (state, token) => {state.token = token}
}
const actions = {
// 登录相关,通过 code 获取 token 和用户信息
loginWechatAuth({commit}, code) {
const data = {code: code}
return new Promise((resolve, reject) => {loginByCode(data)
.then(res => {
// 存用户信息,token
commit('SET_USERINFO', saveUserInfo(res.data.user))
commit('SET_TOKEN', saveToken(res.data.token))
resolve(res)
})
.catch(error => {reject(error)
})
})
},
// 设置状态
setLoginStatus({commit}, query) {if (query === 0 || query === 1) {
// 上线打开注释,本地调试注释掉,保持信息最新
removeToken()
removeUserInfo()}
// 设置不同的登录状态
commit('SET_LOGIN_STATUS', saveLoginStatus(query))
},
// 登出
fedLogOut() {
// 删除 token,用户信息,登陆状态
removeToken()
removeUserInfo()
removeLoginStatus()}
}
export default {
namespaced: true,
state,
mutations,
actions
}
在根目录下.env 开头的三个文件中设置微信 appID
VUE_APP_WECHAT_APPID='12345678' 复制代码
授权再也难不住我了,如果哪里有问题希望大家给我留言纠正,互相学习
关于我
您可以扫描添加下方的微信并备注 Soul 加交流群,给我提意见,交流学习。
如果对你有帮助送我一颗小星星(づ~3~)づ╭❤~