Vue中實現路由、請求攔截器


前后端分離模式已然成為現在的主流模式,鑒權方式從原始的 Session 到現在的 jwt、oauth2 等等方式,無論是哪一種方式,在前端,我們都要通過使用攔截器來實現權限認證等系列操作,我們來講講 Vue 中的路由攔截器與請求攔截器中的實現方法。

用到的組件

  • vue-router
  • axios

請求攔截器

首先我們創建一個文件,用來封裝 axios 的一些基礎方法或配置,我把這個文件命名為 axios.js

import axios from 'axios'
import router from '../router'

axios.defaults.withCredentials = true;  // 設置cross跨域 並設置訪問權限 允許跨域攜帶cookie信息

axios.defaults.headers.post['Content-Type'] = 'application/json'
axios.defaults.headers.put['Content-Type'] = 'application/json'

// http request 攔截器
axios.interceptors.request.use(
  config => {
    return config;
  },
  error => {
    return Promise.reject(error);
  }
);

// http response 攔截器
axios.interceptors.response.use(
  response => {
    return response;
  },
  error => {
    return Promise.reject(error) // 返回接口返回的錯誤信息
  }
);

export default function () {
  return axios
}

http request 攔截器,即請求攔截器。
例:當你本地存在 token 時,可以在請求攔截器中將 token 追加到請求header 里,就像這樣:

// http request 攔截器
axios.interceptors.request.use(
  config => {
    let token = localStorage.getItem('token');
    if (token) {
      config.headers.Authorization = token;
    }
    return config;
  }
);

服務器接收到請求后,對這個 token 進行校驗,通過 token 來判定是否返回你想要的數據。

請求攔截器寫好了,那響應攔截器有什么作用呢?

假如這個時候你正在用戶中心刪除某一條數據,刪除的請求加上 token 發送給了服務端后,服務端給你返回了 401 狀態碼,表示你的 token 已經失效了,你需要重新登錄。

這時候問題來了,你不可能在每一個成功的請求里都判斷一下 狀態碼是否是 401 或 token 是否失效吧?這時候響應攔截器就該登場了。

// http response 攔截器
axios.interceptors.response.use(
  response => {
    // 未登錄或會話已過期
    if ('401' === response.data.code) {
      // 重定向到登錄頁
      router.replace({
        path: '/auth/login',
        query: {redirect: router.currentRoute.fullPath}
      })
    }
    return response;
  },
  error => {
    if (500 === error.response.status) {
      // 服務端異常  
    }
    return Promise.reject(error) // 返回接口返回的錯誤信息
  }
);

以上示例代碼,在響應攔截器中,判斷了每一次服務端返回的狀態碼是否是 401,如若是的,將會重定向到登錄頁,此類場景也就是登錄狀態失效,需要用戶重新授權登錄。

這里要注意的是,這里所說的狀態碼是自定義的狀態,並非請求的 Status Code,如果服務端返回的 Status Code 不是 200,則會走到攔截器的 error 里。

路由攔截器

請求攔截器實現了,但現在還有一個問題。
在單頁面應用里,使用路由跳轉頁面,在切換頁面沒有請求的情況下,如何校驗權限呢?

路由攔截器登場,我們直接在 router.js 文件里編寫路由攔截器。

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router);

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/user',
      name: 'user',
      component: () => import('@/views/User.vue'),
      meta: {
        auth: true,
        title: '用戶中心'
      }
    },
    {
      path: '/auth/login',
      name: 'login',
      component: () => import('@/views/auth/Login.vue'),
      meta: {
        auth: false
      }
    }
  ]
});

// 路由攔截器
router.beforeEach(async (to, from, next) => {
  if (to.matched.some(record => record.meta.auth) && to.meta.auth) { // 判斷該路由是否需要登錄權限
    let token = localStorage.getItem('token');
    if (token) { // 獲取當前的 token 是否存在
      next()
    } else {
      // 不存在 token,需要重新認證
      next({
        path: '/auth/login',
        query: {
          redirect: to.fullPath
        }
      })
    }
  }
  next();
});

export default router

在路由文件中添加路由攔截器,如上所寫。
在每個路由中增加 meta.auth, auth = true 代表此路由頁面需要進行權限認證后才可以訪問,否則反之。

每一次路由跳轉都會經過路由攔截器,在攔截器中根據 meta.auth 判斷是否需要鑒權。本文為了新手便於理解,去除了一些比較復雜的代碼,例如 狀態管理 Vuex。

至此,一個簡單的權限認證就做好了。在這兩種攔截器上,不局限於只使用它來做鑒權,可以利用攔截器來實現自己其他的業務邏輯。

轉載 https://www.wispx.cn/article/vue-in-the-implementation-of-routing-request-interceptors.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM