路由攔截
登錄攔截邏輯
第一步:路由攔截
首先在定義路由的時候就需要添加一個自定義字段requireAuth,用於判斷訪問是否需要登錄,如果用戶已經登錄,則順利進入路由,
否則就進入登錄頁面。
const routes = [
{
path:'/',
name:'/',
component:index
},
{
path:'/repository',
name:'repository',
meta:{
requireAuth:true, //添加這個字段,標識進入這個路由是需要登錄的
},
component:Repository
},
{
path:'/login',
name:'login',
component:Login
}
];
定義完路由後,我們主要是利用vue-router提供的鉤子函數beforeEach()對路由進行判斷
router.beforeEach((to,from,next) => {
if(to.meta.requireAuth){
if(store.state.token){
next()
}else{
next({path:'/login',query:{redirect:to.fullPath}})
}
}else{
next()
}
})
每個鉤子方法接收三個參數
*to:Route:即將要進入的目標 路由對象
*from:Route:當前導航正要離開的路由
*next:Funtion:一定要調用該方法來resolve這個鉤子。執行效果依賴next方法的調用參數
*next():管道中的下一個鉤子。入歐歐冠全部鉤子執行完了,則導航的狀態就是confirmed 即確認的。
*next(false):中斷當前的導航。如果瀏覽器的URL變了(可能是用戶手動或者瀏覽器後退按鈕),那麼URL地址會充值到from路由對應的地址。
*next(’/’)或者next({path:’/’}):跳轉到一個不同的地址,當前導航被中斷,然後進行一個新的導航。
要確保調用next方法,否則鉤子就不會被resolved
其中,to.meta就使我們自定義的數據,其中就包括我們剛剛定義的requiredAuth字段,通過這個字段來判斷是否需要登錄權限,需要的話,同時當前應用不存在token,則跳轉到登錄頁面,進行登錄,登錄成功後轉到目標路由。
登錄攔截到這裏就結束了嗎?並沒有,這種方式只是簡單地路由前端控制,並不能真正阻止用戶訪問權限需要登錄權限的路由。還有一種情況就是,當前token失效了,但是token依然保存在本地。這時候你去訪問需要登錄權限的路由時,實際上應該讓用戶重新登錄。
這個時候就需要結合http 攔截器 +後端接口返回的http 狀態碼來判斷。
第二部:攔截器
想要統一護理所有http請求和響應,就得用上axios的攔截器,通過配置http response inteceptor,當後端接口返回401 Unauthorized(未授權),讓用戶重新登錄;
axios.interceptors.request.use(
config =>{
if(store.store.token){//判斷是否存在token,如果存在的話,則每個http header都加上token
config.headers.Authorization = ·token ${store.state.token}·;
}
return config;
},
err => {
return Promise.reject(err);
}
)
axios.interceptors.response.use(
response => {
return response;
},
error => {
if(error.response){
switch(errot.response.status){
case 401:
//返回401清除token信息並跳轉到登錄頁面
store.commit(types.LOGOUT);
router.replace({
path:'Login',
query:{redirect:router.currentRouter.fullPath}
})
}
}
return Promise.reject(error.response.data)
}
)
二、http攔截
攔截器
首先我們要明白設置攔截器的目的是什麼,當我們需要統一處理http請求和響應式我們通過設置攔截器處理會方便的多。
這個項目我引入了element-ui框架,所以我是結合element中loading和message組件來處理的,我們可以單獨建立一個http的js文件處理axios,再到main.js中引入。
/*
*http配置
*/
//引入axios以及element ui中的loading和message組件
import axios from 'axios'
import {Loading,Message} from 'element-ui'
//超時時間
axios.defaults.timeout = 5000
//http請求攔截器
var loadinginstace;
axios.interceptors.request.use(
config =>{
loadinginstace = Loading.service( { fullscreen : true } );
return config;
},error =>{
loadinginstace.close();
Message.error({
message:'加載超時'
})
return Promise.reject(error);
}
)
export default axios
這樣我們就同一處理了http請求和響應的攔截,當然我們可以根據具體的業務要求更改攔截中的處理。