跳到主要內容
前端開發

Nuxt 2 Middleware:進頁面前做登入驗證

整理 Nuxt 2 用 middleware 在頁面渲染前先做驗證的做法——在 middleware 資料夾新增檔案、頁面用 middleware 屬性指定要套用哪個驗證、meta 帶自訂欄位判斷是否需要登入,沒通過就用 redirect() 導回登入頁。Nuxt 3 之後改用 defineNuxtRouteMiddleware,寫法不同。

W

Nuxt 的 middleware(中介軟體)在頁面真正渲染之前先執行,可以用來做「進這個頁面之前,先檢查有沒有權限」這類需要提前攔截的邏輯。

順帶一提:vue-router 在 Nuxt 裡不是直接可用的

Nuxt 底層雖然用 vue-router,但預設不會讓你直接操作 vue-router 的 API(例如直接寫 router.beforeEach),Nuxt 把路由設定包裝在自己的檔案系統路由與 middleware 機制裡。真的需要直接控制 vue-router 的底層行為,可以另外安裝 @nuxtjs/router,但多數需求(包含這篇的登入驗證)用 middleware 就能處理。

新增 middleware

middleware/auth.js

export default ({ route, redirect }) => {
  if (route.meta[0].requiresAuth) {
    console.log('需要驗證');
    const authState = false; // 實際專案會讀 store 或 cookie 判斷

    if (!authState) {
      // 若沒有登入就導回登入頁
      return redirect('/');
    }
  }
};

redirect 是 Nuxt 的 middleware context 提供的方法,呼叫它會中斷原本的頁面渲染,改導向指定的路徑。

在頁面裡套用

<script>
export default {
  layout: 'login',
  middleware: 'auth',
  meta: {
    requiresAuth: true,
  },
  data() {
    // ...
  },
};
</script>

middleware: 'auth' 的值對應 middleware/auth.js 的檔名,meta.requiresAuth 則是自訂欄位,讓同一支 middleware 可以套用在多個頁面上,各自用 meta 決定要不要真正檢查。

route.meta[0]——這個用陣列索引存取 meta 是 Nuxt 2 一個容易搞混的地方:多層 layout/頁面疊加時,meta 實際上會是一個陣列(對應各層各自的 meta 設定),單一頁面沒有巢狀 layout 疊加時,meta[0] 通常就是你要的那個物件,但這個索引寫法本身很容易讓人誤解成陣列裡有多筆不同資料,是 Nuxt 2 這套機制設計上不太直覺的地方。

現在還適用嗎

進頁面前先驗證的概念完全沒變,但 Nuxt 3 之後 middleware 的寫法整個重寫過,meta[0] 這種容易誤解的陣列索引寫法也不存在了,整理在《Nuxt 3 的 Route Middleware:defineNuxtRouteMiddleware》。

參考資料

分享這篇