詳解vue微信網(wǎng)頁(yè)授權(quán)最終解決方案
vue微信網(wǎng)頁(yè)授權(quán),基于vue-cli3.0+webpack 4+vant ui + sass+ rem適配方案+axios,開(kāi)發(fā)的微信授權(quán)方案。項(xiàng)目地址:vue-wechat-auth
參考了[vue-wechat-login],思路有些不同,本文基于進(jìn)入所有頁(yè)面都必須先授權(quán)的操作。
與之前寫(xiě)的授權(quán)不同之處
這次的邏輯全部在router的beforeEach進(jìn)行,相較更加簡(jiǎn)潔明。之前是在一個(gè)中間頁(yè)author.vue中,加上微信授權(quán)要跳轉(zhuǎn)很多次
在這里你能找到
微信網(wǎng)頁(yè)授權(quán)前端解決方案,官方文檔
如何使用Natapp(ngrok)進(jìn)行微信本地開(kāi)發(fā)調(diào)試,官方文檔
如何配置微信開(kāi)發(fā)測(cè)試賬號(hào)
關(guān)于測(cè)試賬號(hào)和本地開(kāi)發(fā)設(shè)置
由于文章過(guò)長(zhǎng)這里[微信測(cè)試賬號(hào)和本地開(kāi)發(fā)調(diào)試]記得回來(lái)哦~
微信網(wǎng)頁(yè)授權(quán)
都設(shè)置好了那就開(kāi)始微信網(wǎng)頁(yè)開(kāi)發(fā)第一步也是最重要的一步,微信網(wǎng)頁(yè)授權(quán)
關(guān)于授權(quán)你首先要清楚的是,服務(wù)端要用到的是微信openid還是微信unionid,這兩者的區(qū)別是,如果你要的是unionid,那么你需要在[微信開(kāi)放平臺(tái)]去綁定測(cè)試賬號(hào)。測(cè)試號(hào)的appId和appsecret在微信公眾平臺(tái)的測(cè)試號(hào)里找。微信公眾號(hào)后臺(tái)->開(kāi)發(fā)者工具->公眾平臺(tái)測(cè)試帳號(hào)->進(jìn)入

如果你不需要unionid,那這個(gè)你就可以省略, 如果服務(wù)端是需要unionid的那不綁定的話授權(quán)會(huì)把報(bào)錯(cuò)的。記得問(wèn)一下服務(wù)端開(kāi)發(fā)人員哦。
開(kāi)發(fā)
首先我們看下微信授權(quán)的流程圖,關(guān)于微信網(wǎng)頁(yè)授權(quán)
前端需要做的是
第一步:用戶同意授權(quán),獲取code,拼接微信授權(quán)地址,redirect_uri就是你的當(dāng)前地址,關(guān)于appid有些人是通過(guò)接口獲取的,我這里就直接寫(xiě)在項(xiàng)目全局變量里了VUE_APP_WECHAT_APPID,用戶授權(quán)成功后微信會(huì)攜帶code和status跳回來(lái)
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
第二步,訪問(wèn)登錄接口,將code傳給服務(wù)端,小哥哥進(jìn)行一系列的操作,通過(guò)code換取網(wǎng)頁(yè)授權(quán)access_token,拉取用戶信息(需scope為 snsapi_userinfo),返回是否登錄成功,成功后返回用戶信息和登錄令牌 token

在permission.js中路由攔截進(jìn)行這一系列操作,代碼注釋很詳細(xì)了
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)
// 頁(yè)面標(biāo)題
document.title = getPageTitle(to.meta.title)
if (loginStatus === 0) {
// 微信未授權(quán)登錄跳轉(zhuǎn)到授權(quán)登錄頁(yè)面
const url = window.location.href
// 解決重復(fù)登錄url添加重復(fù)的code與state問(wèn)題
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
}
// 設(shè)置微信授權(quán)回調(diào)地址
wechatAuth.redirect_uri = loginUrl
// 無(wú)論拒絕還是授權(quán)都設(shè)置成1
store.dispatch('user/setLoginStatus', 1)
// 跳轉(zhuǎn)到微信授權(quán)頁(yè)面
window.location.href = wechatAuth.authUrl
} else if (loginStatus === 1) {
// 用戶已授權(quán),獲取code
try {
// 通過(guò)回調(diào)鏈接設(shè)置code status
wechatAuth.returnFromWechat(to.fullPath)
} catch (err) {
// 失敗,設(shè)置狀態(tài)未登錄,刷新頁(yè)面
store.dispatch('user/setLoginStatus', 0)
location.reload()
}
// 同意授權(quán) to.fullPath 攜帶code參數(shù),拒絕授權(quán)沒(méi)有code參數(shù)
const code = wechatAuth.code
if (code) {
// 拿到code 訪問(wèn)服務(wù)端的登錄接口
store
.dispatch('user/loginWechatAuth', code)
.then(res => {
// 成功設(shè)置已登錄狀態(tài)
store.dispatch('user/setLoginStatus', 2)
next()
})
.catch(() => {
// 失敗,設(shè)置狀態(tài)未登錄,刷新頁(yè)面
store.dispatch('user/setLoginStatus', 0)
location.reload()
})
} else {
store.dispatch('user/setLoginStatus', 0)
location.reload()
}
} else {
// 已登錄直接進(jìn)入
next()
}
})
登錄成功后存用戶信息,token。訪問(wèn)所有的接口的時(shí)候都會(huì)在header攜帶token,如果token失效了,服務(wù)端會(huì)返回401,做退出操作,刪除登錄狀態(tài),用戶信息,token,刷新頁(yè)面重新進(jìn)入。
request.js
// 登錄超時(shí),重新登錄
if (res.status === 401) {
store.dispatch('user/fedLogOut').then(() => {
location.reload()
})
}
用戶登錄后將token和用戶信息存入storage中,登錄狀態(tài)設(shè)置到cookie里,store user中主要是進(jìn)行用戶信息存貯獲取刪除的操作
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(), // 登錄狀態(tài)
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 = {
// 登錄相關(guān),通過(guò)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)
})
})
},
// 設(shè)置狀態(tài)
setLoginStatus({ commit }, query) {
if (query === 0 || query === 1) {
// 上線打開(kāi)注釋,本地調(diào)試注釋掉,保持信息最新
removeToken()
removeUserInfo()
}
// 設(shè)置不同的登錄狀態(tài)
commit('SET_LOGIN_STATUS', saveLoginStatus(query))
},
// 登出
fedLogOut() {
// 刪除token,用戶信息,登陸狀態(tài)
removeToken()
removeUserInfo()
removeLoginStatus()
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
在根目錄下.env開(kāi)頭的三個(gè)文件中設(shè)置微信appID
VUE_APP_WECHAT_APPID='12345678'復(fù)制代碼
授權(quán)再也難不住我了,如果哪里有問(wèn)題希望大家給我留言糾正,互相學(xué)習(xí)
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
移動(dòng)端底部導(dǎo)航固定配合vue-router實(shí)現(xiàn)組件切換功能
經(jīng)常遇到這樣的需求,移動(dòng)端中的導(dǎo)航并不是在頂部也不是在底部,而是在最底部且是固定的,當(dāng)我們點(diǎn)擊該導(dǎo)航項(xiàng)時(shí)會(huì)切換到對(duì)應(yīng)的組件。這篇文章主要介紹了移動(dòng)端底部導(dǎo)航固定配合vue-router實(shí)現(xiàn)組件切換功能,需要的朋友可以參考下2019-06-06
vue3使用自定義指令實(shí)現(xiàn)el dialog拖拽功能示例詳解
這篇文章主要為大家介紹了vue3使用自定義指令實(shí)現(xiàn)el dialog拖拽功能示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Vue+tsx使用slot沒(méi)有被替換的問(wèn)題
本文主要介紹了Vue+tsx使用slot沒(méi)有被替換的問(wèn)題,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08
在Vue項(xiàng)目中引入騰訊驗(yàn)證碼服務(wù)的教程
這篇文章主要介紹了在Vue項(xiàng)目中引入騰訊驗(yàn)證碼服務(wù)的教程,需要的朋友可以參考下2018-04-04
vue elementUI table 自定義表頭和行合并的實(shí)例代碼
這篇文章主要介紹了vue elementUI table 自定義表頭和行合并的實(shí)例代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05
解決vue無(wú)法加載文件D:\Program Files\nodejs\node_global\vue.ps1,
這篇文章主要給大家介紹了關(guān)于解決vue無(wú)法加載文件D:\Program Files\nodejs\node_global\vue.ps1,因?yàn)樵诖讼到y(tǒng)上禁止運(yùn)行腳本的相關(guān)資料,這個(gè)報(bào)錯(cuò)是由于在系統(tǒng)上禁止運(yùn)行腳本導(dǎo)致的,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
如何將HTML頁(yè)面改寫(xiě)到vue項(xiàng)目中詳解
html和vue都是前端技術(shù)中非常重要的一部分,其中html是web開(kāi)發(fā)的基石,而vue則是現(xiàn)代化的前端開(kāi)發(fā)框架之一,下面這篇文章主要給大家介紹了關(guān)于如何將HTML頁(yè)面改寫(xiě)到vue項(xiàng)目中的相關(guān)資料,需要的朋友可以參考下2024-08-08
詳解基于Vue2.0實(shí)現(xiàn)的移動(dòng)端彈窗(Alert, Confirm, Toast)組件
這篇文章主要介紹了詳解基于Vue2.0實(shí)現(xiàn)的移動(dòng)端彈窗(Alert, Confirm, Toast)組件,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
elementPuls 表格反選實(shí)現(xiàn)示例代碼
這篇文章主要介紹了elementPuls 表格反選實(shí)現(xiàn)示例代碼,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2024-07-07

