【科技友瘋狂】JWT 認證安全全攻略:開發者最容易忽略的 5 大風險

關鍵字 :全端工程師修煉日記JWT資訊安全Token實作身分驗證

你可能已經用過 JWT 來實作登入系統:
使用者登入後,系統簽發一組 Token,接下來每個 API 請求都帶著這個 Token,就能驗證身份。

聽起來簡單又有效,但如果你沒設好:

  • Token 可能被竊取

  • 使用者權限可能被偽造

  • 系統可能毫無防備地被入侵

JWT 的確方便,但它不是萬能,實作不當反而變成系統最大的漏洞。

這篇文章帶你從實作邏輯到攻防觀念,了解 JWT 的正確使用方式與常見錯誤。


一、JWT 是什麼?為什麼被廣泛使用?

JWT(JSON Web Token)是一種以 JSON 格式編碼、具有簽章機制的 Token。
常用於前後端分離架構的身份驗證。

結構:

header.payload.signature
  • Header:定義演算法與類型

  • Payload:包含用戶資料(如 userId, role)

  • Signature:用來驗證資料是否被竄改(以 secret 或私鑰簽名)

JWT 可由伺服器產生,客戶端保存(如 localStorage、cookie)並在每次請求中附上。


二、JWT 正確的產生與驗證流程(Node.js 範例)

const jwt = require('jsonwebtoken');

const token = jwt.sign(
  { userId: 123, role: 'user' },
  'mySecretKey',
  { expiresIn: '1h' }
);

const decoded = jwt.verify(token, 'mySecretKey');

三、最常見的 5 大安全誤區

1. 不設過期時間(exp)

錯誤:

jwt.sign(payload, secret);  // 沒有 expiresIn

這樣產生的 token 永遠有效,被竊取後可永久使用。

正確:

jwt.sign(payload, secret, { expiresIn: '1h' });

2. 把敏感資料放進 payload

JWT 的內容是 base64 編碼,不是加密!任何人都能 decode。

// 不該放:
{ "password": "123456", "cardNumber": "****" }

建議: payload 只放必要的識別資訊(如 userId, role),敏感資料不要放進去。


3. 演算法被降級攻擊

攻擊者可自行產生:

{ "alg": "none" }

如果伺服器不驗證演算法,就可能讓未簽名的 token 被接受。

防禦方式:

  • 永遠指定使用的演算法(如 HS256)

  • 拒絕處理 alg: none 的 token


4. Secret 選得太弱或公開

選擇太簡單的 secret(如 123456),或把 secret 寫在前端代碼中,將使所有 token 都可被偽造。

建議:

  • Secret 至少 32 字元以上,隨機產生

  • 使用 .env 管理環境變數,切勿硬編碼在程式碼中


5. 未驗證權限角色

JWT 中的 payload 可能有:

{ "userId": 1, "role": "admin" }

攻擊者若能偽造或重放舊 token,可能藉此取得不該有的權限。

建議:

  • 每次 API 請求都要重新驗證該用戶是否真的具備對應角色權限

  • 不要僅憑 token 裡的 role 判斷權限


四、JWT 要儲存在哪裡才安全?

儲存位置 優點 缺點
localStorage 操作簡單 易受 XSS 攻擊
cookie(httpOnly) 可避免 XSS 需防 CSRF
sessionStorage 僅限同一分頁 關閉即失效

建議: 若能設計 CSRF 防禦機制,使用 httpOnly cookie 儲存 token 是較安全的選擇。


五、結語:JWT 是利器也是風險,安全實作才是關鍵

JWT 不是用來保存資料的容器,而是短期憑證。


只要實作正確,它能讓系統驗證機制簡潔高效;但若忽略細節,它也可能成為攻擊者入侵的後門。

安全性從來都不只是有沒有加密,而是你怎麼控制使用者的行為範圍與資料存取邏輯。

★博文內容均由個人提供,與平台無關,如有違法或侵權,請與網站管理員聯繫。

★文明上網,請理性發言。內容一周內被舉報5次,發文人進小黑屋喔~

評論