昨天我們學會了如何核發 JWT。但如果我們要保護「新增寶可夢」、「修改圖鑑」這些 API,難道要在每一支 API 裡面都寫一次「檢查 Token 有沒有效」的 if...else 邏輯嗎?
絕對不要!這違反了 DRY (Don't Repeat Yourself) 原則。今天,我們將利用 Express 的 Middleware (中介軟體) 來打造一道全自動的防護罩。
在 Express 中,當前端發送一個請求過來,它並不是直接到達目標 API,而是會先經過一層一層的 Middleware,就像剝洋蔥一樣:
401 Unauthorized,連 API 都不給進。req.user,然後呼叫 next() 繼續往內層走。req.user,因為能走到這一步的人,絕對已經通過驗證了!我們建立 src/middleware/auth.ts 來實作這個守衛:
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
// 擴充 Express 的 Request 型別,讓我們可以把 user 塞進去
declare global {
namespace Express {
interface Request {
user?: any;
}
}
}
export const requireAuth = (req: Request, res: Response, next: NextFunction) => {
// 1. 從 Headers 找出 Token (格式通常是 Bearer xxxx)
const authHeader = req.headers.authorization;
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return res.status(401).json({ error: '缺少授權 Token' });
}
const token = authHeader.split(' ')[1];
try {
// 2. 驗證這張通行證是不是我們簽發的、有沒有過期
const decoded = jwt.verify(token, process.env.JWT_SECRET as string);
// 3. 把解密出來的資訊 (如 userId, role) 塞進 req,方便後續 API 使用
req.user = decoded;
// 4. 驗證通過,放行!呼叫下一個處理者
next();
} catch (error) {
// 只要過期或是被竄改,verify 就會噴 Error,進入這裡
return res.status(401).json({ error: 'Token 無效或已過期' });
}
};
使用方法非常優雅,只要在路由加上 requireAuth 即可:
// 這支 API 被防護罩包起來了!
app.use('/api/holdings', requireAuth, holdingRoutes);

在沒有帶 Token 的情況下發送 GET 請求,被系統無情地用
401 Unauthorized與「缺少授權 Token」擋下來的畫面。
我們成功利用 Middleware 把驗證邏輯抽離出來,程式碼變得極度乾淨且安全!防護罩建立好了,明天我們終於可以來實作最核心的「取得寶可夢持有列表」API 了!