Nuxt.js 導航守衛

前言

這一篇將會記錄該如何製作導航守衛,由於一般情況下 Nuxt 做法與在 Vue 下是不同的,所以就記錄一下該如何製作 Nuxt 導航守衛吧

導航守衛

首先先來講講導航守衛是什麼東西,通常我們在撰寫 Vue 時會搭配 Vue-Router,而 Vue-router 底下有一個 API 功能是 導航守衛

普遍來講最常使用的 API 有這兩種

  • router.beforeEach
  • router.afterEach

beforeEachafterEach 差異在於 afterEach 沒有提供 next 的函數,只需要知道這一個重點就可以看出差異。

那麼通常我們在撰寫 Vue 的時候都會在 main.js 下加入一段像這樣的程式碼

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
const url = `${process.env.VUE_APP_APIPATH}/api/user/check`;
axios.post(url).then((response) => {
if (response.data.success) {
next();
} else {
store.dispatch('updateMessage', {
message: `登入失敗惹Σ( ° △ °|||)︴${response.data.message}`,
status: 'danger',
});
next({
path: '/login',
});
}
});
} else {
next();
}
});

並且針對 router.js 修改加入 meta: { requiresAuth: true }

1
2
3
4
5
6
7
8
9
10
11
12
{
path: '/admin',
name: '',
component: () => import('@/views/admin/Dashboard.vue'),
children: [
{
path: '',
name: 'Console',
component: () => import('@/components/admin/Console.vue'),
meta: { requiresAuth: true },
},
...(以下略)

範例程式碼來源:RagnarokShopV3

但是在 Nuxt 卻又不同了,因為在 Nuxt.js 並沒有 main.js,而且一般情況下我們也不會去自定義 router.js,畢竟在 Nuxt.js router 是自動生成的。

(詳情可看這一篇:Nuxt Route 設置)

那麼該如何解決這個問題呢?那這就是本篇的重點了

Nuxt 導航守衛

這邊我已經預先準備好一個初始專案,後面會提供 GitHub 範例。

首先撰寫 Nuxt 導航守衛的時候,不能將它當作插件來使用,因為這樣並不是我們所需要,我們則是要將它當作 middleware 來使用,當用戶進入該頁面的時候會先經過這個 middleware,這樣就可以阻擋下來驗證是否登入 or 等等。

起手式

所以先在 middleware 底下建立一個 routerAuth.js,而這邊我們會使用到 Context 中的 API,也就是 route、redirect,所以一開始程式碼會如下

1
2
3
export default ({ route, redirect }) => {
console.log('routerAuth');
}

接下來就丟著不理它,讓我們開啟欲加入守衛的 .vue 檔,例如我新增了 Auth 資料夾,底下有 index.vue、admin.vue 這兩個檔案,然後替 admin.vue 增加以下程式碼

1
2
3
4
5
6
7
8
<script>
export default {
middleware: 'routeAuth',
meta: {
requiresAuth: true
}
};
</script>

admin.vue

只需要加入 middleware & 檔案名稱,Nuxt 就會去抓取 middleware 資料夾底下的 middleware

meta: { requiresAuth: true } 則是我們稍後會使用到的東西,基本上就跟 Vue-router 差不多。

所以我們這時候可以嘗試去進入這個 router 看看,我們可以看到 console 會出現 routerAuth 訊息

routerAuth

取得 requiresAuth

接下來我們確保了 middleware 是可以正常運作的,那麼就要來試著取得 requiresAuth,這邊我就不廢話了,直接提供程式碼給各位看

1
2
3
4
export default ({ route, redirect }) => {
console.log('routerAuth')
console.log(route.meta)
}

只需要這樣寫我們就可以取得 requiresAuth

取得 requiresAuth

所以就可以知道我們可以透過 route.meta 來取得 components 的 requiresAuth 狀態,但是這邊要注意,正確取得的方式,因為 route.meta 是一個陣列,所以完整一點寫法如下

1
2
3
4
export default ({ route, redirect }) => {
console.log('routerAuth')
console.log(route.meta[0].requiresAuth)
}

正確取得 requiresAuth

那麼我們就可以依照這個邏輯去做調整成屬於我們的 middleware,所以我這邊就直接提供程式碼。

1
2
3
4
5
6
7
8
9
10
export default ({ route, redirect }) => {
if (route.meta[0].requiresAuth) {
console.log('需要驗證');
...(可能開始呼叫 API 驗證登入狀態等等動作)
const authStates = false; // 改為 true 就可以進入了
if (!authStates) { // 若沒有登入就使用返回登入頁面
return redirect('/auth/login')
}
}
}

以上就是 Nuxt 的導航守衛驗證方式,最後這邊提供上 GitHub 範例 Repos

GitHub: Nuxt-routeAuth

可以給點牡蠣。
Google AD