Skip to content

Vue Router 導航守衛:守護您的應用程式頁面安全

在開發網頁應用時,我們常需要限制某些頁面的存取權限。導航守衛 (Navigation Guards) 就如同網頁的保安或海關,當使用者試圖切換路徑時,守衛會攔下請求並執行檢查,例如:檢查登入狀態、驗證權限,最後決定放行、取消,或是改派到其他頁面。

核心觀念:全域前置守衛 beforeEach

最常用的導航守衛是 router.beforeEach。它會在導航觸發後、進入目標頁面元件前被呼叫。您可以透過 to 參數取得目標路由的資訊。常用的情境如下:

  • 驗證使用者是否已登入(Token 檢查)。
  • 檢查使用者是否有特定職務權限(Role-based Access Control)。
  • 頁面切換時的數據預載或進度條顯示。

檔案架構與內容

我們將新增一個 Login.vue 頁面來進行使用者登入。

src/
 ├─ router/
 │   └─ index.js
 ├─ views/
 │   ├─ member/
 │   │   ├─ Profile.vue
 │   │   └─ Orders.vue
 │   ├─ Member.vue
 │   ├─ Login.vue         # 使用者登入
 │   └─ ...
 ├─ App.vue
 └─ main.js

實作步驟:定義需要權限的路由

改寫程式碼

在導航守衛加入之前,我們需要改寫一下程式碼,讓之後的應用更方便。

js
import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
...
});

export default router;

指定需要定義權限的路由

首先,我們在路由表中使用 meta 欄位來標記哪些路徑需要經過驗證。將需要加入導航守衛的路由,設定 meta: { requiresAuth: true }

js
...

const router = createRouter({
...,
  routes: [
...,
    {
      path: '/member',
      component: () => import('@/views/Member.vue'),
      meta: { requiresAuth: true },
      children: [ 略... ],
    },
...
  ],
});

...

TIP

如果您有巢狀路由,to.meta 會自動合併父層與子層的 meta 標籤,這讓您只需要在父層路由定義 requiresAuth: true,底下所有的子路由都會受到保護。

撰寫攔截邏輯

利用 router.beforeEach 檢查目標路由是否包含 requiresAuth,並確認 localStorage 中是否存在 token。

js
...

const router = createRouter({
...,
});

router.beforeEach((to) => {
  // 1. 檢查目標路由是否需要登入權限
  if (to.meta.requiresAuth) {
    const token = localStorage.getItem('token');

    // 2. 如果有 token,放行進入頁面
    if (token) {
      return true;
    }

    // 3. 無 token,強制重新導向至登入頁
    return {
      path: '/login',
    };
  }
  return true;
});

...

重要觀念

在實務專案中,僅檢查 token 「是否存在」是不夠的,通常還會呼叫 API 驗證 token 的「有效性」或解析 JWT 過期時間。

登入頁面實作

在登入元件中,當使用者成功登入後,我們將 token 存入瀏覽器儲存空間,並引導使用者前往受保護的頁面。

Login.vue

vue
<script setup>
import { useRouter } from "vue-router";

const router = useRouter();

function setToken() {
  localStorage.setItem("token", "user_access_token_sample");
  router.push("/member");
}
</script>

<template>
  <h1>Login</h1>
  <input type="button" value="點我模擬登入" @click="setToken" />
</template>

導航守衛的傳回值說明

在 Vue Router 4 中,beforeEach 的傳回值決定了導航的去向:

  • true:放行導航。
  • false:取消導航,停留在目前頁面。
  • { path: '/login' }:路由物件,往指定的路徑。

總結

透過「路由 Meta 設定」與「導航守衛」的結合,能以極精簡的程式碼管理整站的頁面存取權限。這不僅能防止未授權使用者進入敏感頁面,更能大幅提升 Web App 的使用者體驗。