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實作步驟:定義需要權限的路由
改寫程式碼
在導航守衛加入之前,我們需要改寫一下程式碼,讓之後的應用更方便。
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
略...
});
export default router;指定需要定義權限的路由
首先,我們在路由表中使用 meta 欄位來標記哪些路徑需要經過驗證。將需要加入導航守衛的路由,設定 meta: { requiresAuth: true }。
略...
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。
略...
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
<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 的使用者體驗。
