先後端分離開發、獨立部署,爲前端的開發人員提供了極大的便利,同時也帶來了新的挑戰。前端
這是重點:前端須要根據用戶的登陸態或角色身份進行權限控制攔截,以展現對應的功能模塊或者是展現對應的數據。vue
接下來胡哥就給小夥伴分享下在實際項目中的基於Vue+VueRouter+Vuex+Axios的用戶登陸態路由級和接口級攔截的原理與實現。ios
// 藉助於VueRouter的鉤子函數beforeEach,判斷是否有權限進入,執行next()或next(false) router.beforeEach((to, from ,next) => { // next() 經過,容許進入 // next(false) 禁止,不容許進入該模塊 })vue-router
攔誰vuex
// 在VueRouter的路由配置項中,增長meta屬性,設置是否須要權限驗證的標記
// 用戶中心路由
{
path: 'user',
name: 'User',
Component: User,
meta: {
// 須要權限驗證
requireAuth: true
}
}
複製代碼
實現方案npm
安裝vue-routeraxios
npm i vue-router -D
複製代碼
定義路由以及路由設置權限標誌後端
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
// 路由規則
routes: [
{
path: '/',
name: 'Home',
// 引入的模塊默認是已經引入並定義了,這裏很少描述
component: Home,
children: [
{
path: 'index',
name: 'Index',
component: Index,
// 定義元信息
meta: {
// 權限驗證標記 false 不進行校驗攔截
requireAuth: false
}
},
{
path: 'user',
name: 'User',
component: User,
meta: {
// 權限驗證標記 true 進行校驗攔截
requireAuth: true
}
},
{
path: 'login',
name: 'Login',
component: Login,
meta: {
// 權限驗證標記 false 不進行校驗攔截
requireAuth: false
}
}
]
}
]
})
複製代碼
權限攔截斷定服務器
以用戶登陸態做爲標誌,進行登陸驗證session
const router = new VueRouter({
routes: [
// ...
]
})
// 權限攔截-beforeEach路由鉤子函數
router.beforeEach (to, from, next) {
// to 目的路由對象 from 來源路由對象
if (to.match.some(rocode => recode.meta.requireAuth)) {
/**
* 登陸狀態-可以使用aixos進行請求,拉取服務器數據,獲取用戶登陸狀態
* 強烈建議在本地使用localStorage或sessionStorage和vuex共同管理用戶登陸態,避免每次進入時都拉取服務器端接口以驗證用戶是否登陸,額外消耗對服務器的請求,提高用戶體驗
* 若是已登陸,則更新store中存儲的loginName -- 詳細查看下面的store配置
* 未登陸,則直接跳轉走
*/
let isLogin = 已登陸 ? true : false
// 執行攔截斷定
if (!isLogin) {
// 跳轉到登陸模塊
// 處理方式一:藉助next()方法
next({
name: 'Login',
replace: 'true',
// redirectUrl 用於標記登陸後回跳的地址
redirectUrl: to.fullPath
})
// 處理方式二:使用window.loaction.href方式,須要執行next(false)配合使用
window.location.href = '指定的登陸地址?redirectUrl=' + to.fullPath
next(false)
} else {
// 已登陸,直接進入
next()
}
} else {
// 不執行攔截,直接進入該路由
next()
}
}
複製代碼
問題思考
怎麼攔截
藉助axios的攔截器:
interceptors.request.use 請求攔截器
interceptors.response.use 響應攔截器
複製代碼
攔誰
設置特定的接口地址白名單,用因而否進行用戶登陸態權限斷定
不是全部的接口都要進行攔截的,好比:
1. 發送和獲取登陸信息的接口
2. 發送註冊信息的接口
3. 其餘不須要用戶態的接口
複製代碼
實現方案
安裝axios
npm i axios -D
複製代碼
引入axios,添加攔截器
import axios from 'axios'
import router from '@/router'
// 具體數據倉庫對象store配置請往下看
import store from '@/store'
const $http = axios.create({
// 基本配置項
})
// 定義接口地址白名單
const allowUrls = [
'/getUserInfo',
'/addUserInfo'
]
// 請求攔截器 -- 發送請求前,判斷是否存在登陸信息
$http.interceptors.resquest.use((config) => {
// config.url 是請求的URL地址
if (allowUrls.includes(config.url)) {
// 判斷是否登陸 --- 本地信息以及vuex的store信息進行斷定
let isLogin = locationStorage.getItem('isLogin')
if (!isLogin || !store.state.loginName) {
// 攜帶當路由地址,跳轉登陸
// router.currentRoute.fullPath
} else {
return config
}
} else {
// 不須要斷定則直接返回config配置
return config
}
})
// 響應攔截器
$http.interceptors.response.use((res) => {
// 判斷是否須要驗證權限
if (allowUrls.includes(res.config.url)) {
// 判斷是否登陸 --- 本地信息、vuex的store信息以及後端服務器響應回來的是否登陸的標記
let isLogin = locationStorage.getItem('isLogin')
// 約定 code 10011 表示未登陸
if (!isLogin || !store.state.loginName || res.data.code === 10011) {
// 攜帶當路由地址,跳轉登陸
// router.currentRoute.fullPath
} else {
return config
}
} else {
return res
}
})
複製代碼
下載安裝vuex
npm i vuex -D
複製代碼
配置相關項
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {
// 用戶登陸後,獲取暱稱
loginName: ''
},
mutations: {
updateLoginInfo (state, loginName) {
state.loginName = loginName
}
}
})
複製代碼
以上就是胡哥今天給你們分享的內容,喜歡的小夥伴記得收藏、轉發、點擊在看呦…
胡哥有話說,一個有技術,有情懷的胡哥!京東開放平臺首席前端攻城獅。與你一塊兒聊聊大前端,分享前端系統架構,框架實現原理,最新最高效的技術實踐!
長按掃碼關注,更帥更漂亮呦!