“深入淺出 NextJS Middleware 用途說明”
NextJS Middleware 是什麼?
嘿!你有沒有想過在你的 NextJS 應用程式中,每次使用者請求時都能先經過一段中間程序來處理驗證、日誌記錄或其他重要的操作?這就是 Middleware 的用途!它就像是一個守門員,讓你可以在請求抵達最終目的地之前先做些處理工作。
Middleware 在 NextJS 中有很多實用的應用,今天我們就來深入探討它們的用途、如何使用,以及一些實際的應用範例。
Middleware 的用途
Middleware 可以應用在很多場景,包括但不限於:
- 驗證和授權:檢查使用者是否已經登入,並根據其角色授予適當的權限。
- 日誌記錄:記錄每個請求的細節,幫助你追蹤應用程式的使用情況。
- 重定向:根據特定條件將使用者重定向到不同的頁面。
- 處理跨站請求:防止跨站請求偽造(CSRF)攻擊。
- 緩存:對某些靜態資源進行緩存,提高網站的效能。
讓我們透過一些實際的例子來看看如何在 NextJS 中實現這些功能。
如何在 NextJS 中使用 Middleware
NextJS 提供了一個簡單而強大的方式來使用 Middleware。只需在 pages
目錄或其子目錄中創建 _middleware.ts
文件,即可定義中介軟體。
範例:全域性驗證 Middleware
首先,我們來看看如何創建一個全域性的驗證 Middleware,確保所有未經驗證的請求都被重定向到登入頁面。
import { NextRequest, NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';
export async function middleware(req: NextRequest) {
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
const url = req.nextUrl.clone();
if (!token && !url.pathname.startsWith('/auth')) {
url.pathname = '/auth/login';
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
這段代碼會在每個請求被處理之前檢查是否有有效的 JWT token。如果沒有,就將請求重定向到 /auth/login
頁面。
範例:特定路由的 Middleware
有時候,你可能只想對某些特定路由應用 Middleware。例如,假設我們只想對 /dashboard
路由應用驗證邏輯,我們可以這樣做:
// pages/dashboard/_middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';
export async function middleware(req: NextRequest) {
const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
const url = req.nextUrl.clone();
if (!token) {
url.pathname = '/auth/login';
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: [
'/dashboard/:path*',
],
};
這樣一來,只有訪問 /dashboard
路由的請求會被這個 Middleware 處理。
更進一步:Middleware 與其他功能結合
使用 Middleware 進行日誌記錄
Middleware 也可以用來記錄請求的詳細信息,這對於排錯和監控應用程式非常有幫助。下面是一個簡單的日誌記錄 Middleware 範例:
// middleware/logger.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
console.log(`Request received: ${req.method} ${req.url}`);
return NextResponse.next();
}
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
使用 Middleware 進行重定向
有時候,我們需要根據特定條件重定向使用者。例如,當使用者訪問舊版本的網站時,我們希望將他們重定向到新版本的頁面:
// middleware/redirect.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
const url = req.nextUrl.clone();
if (url.pathname.startsWith('/old-version')) {
url.pathname = '/new-version';
return NextResponse.redirect(url);
}
return NextResponse.next();
}
export const config = {
matcher: [
'/old-version/:path*',
],
};
_middleware.tsx
與目錄 middleware
的差異
在 NextJS 中,使用 _middleware.tsx
和在目錄 middleware
中定義中介軟體有一些關鍵的差異。
_middleware.tsx
- 自動應用:在
pages
目錄或其子目錄中創建_middleware.tsx
文件,這些中介軟體會自動應用到該目錄及其子目錄的所有路由。 - 簡單配置:你只需定義一次中介軟體,NextJS 會自動識別並應用它。
- 適用範圍:可以全域性應用,也可以針對特定路由應用。
目錄 middleware
- 自定義組織:這是一個用來組織和管理中介軟體的目錄,可以包含多個中介軟體文件。
- 需要手動引用:需要在特定的路由或 API 處理程序中手動引用這些中介軟體。
- 靈活使用:適合用來管理多個不同用途的中介軟體,如驗證、日誌記錄等,並可以根據需求選擇性應用。
差異對照表
_middleware.tsx | middleware 目錄 | |
---|---|---|
自動應用 | 是 | 否 |
手動引用 | 否 | 是 |
適用範圍 | 目錄及其子目錄的所有路由 | 需要手動選擇應用 |
靈活性 | 中等 | 高 |
組織管理 | 適中 | 高 |
結論
NextJS 的 Middleware 是一個強大且靈活的工具,能讓你在應用程式的請求流程中插入自定義邏輯,從而實現驗證、日誌記錄、重定向等功能。透過合理地使用 Middleware,你可以顯著提升應用程式的安全性和效能。
希望這篇文章能幫助你更好地理解和使用 NextJS 的 Middleware。如果你有任何問題或需要進一步的幫助,歡迎隨時聯繫我。Happy coding!
Middleware 用途對照表
用途 | 描述 | 範例 |
---|---|---|
驗證 | 確認使用者是否登入,並根據角色授予權限 | 檢查 JWT token,重定向到登入頁面 |
日誌記錄 | 記錄每個請求的細節,便於追蹤應用程式的使用情況 | 記錄請求方法和 URL |
重定向 | 根據特定條件重定向使用者到不同的頁面 | 將訪問舊版本頁面的請求重定向到新版本 |
防跨站請求 | 防止跨站請求偽造(CSRF)攻擊 | 檢查和驗證 CSRF token |
緩存 | 對某些靜態資源進行緩存,提高網站效能 | 設置緩存標頭來優化 |
資源加載 |
流程圖如下:
graph TD
A[訪客] -->|發送請求| B[Next.js 伺服器]
B --> C{是否有 _middleware.ts?}
C -->|是| D[執行 _middleware.ts]
C -->|否| E{是否有對應頁面?}
D --> F{中介軟體處理完成?}
F -->|是| E
F -->|否| G[中止請求或重定向]
E -->|是| H[執行頁面邏輯]
E -->|否| I[返回 404 頁面]
H --> J[返回響應]
I --> J
G --> J
希望這篇文章對你有幫助!如果你有任何問題或想法,歡迎在留言區分享。Happy coding!