---
title: "實作JWT驗證所遇到的問題"
description: "記錄在後端系統導入 JWT 驗證時遇到的問題，包含 Token 儲存位置選擇、跨視窗互搶、踢人機制設計及 Redis 整合策略。"
canonical_url: "https://blog.markkulab.net/post/jwt"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/author/mark-ku"
site: "Mark Ku's Blog"
date_published: "2020-07-24 15:01:35 +0300"
category: "Backend"
tags: ["jwt", "authentication", "security", "redis", "backend", "csharp"]
language: "zh-TW"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "轉載或引用請註明作者並附上原文連結"
---

# 實作JWT驗證所遇到的問題

## 實作JWT驗證所遇到的問題

## 對JWT TOKEN 的理解
JWT當初的設計是為了確保在跨組織間安全互相傳遞資料所存在。
但因為JWT無法確保安全性，後來延伸的JWE，但JWE的標準，定義了很多我們不必要的屬性及命名規範，我在想我們應該是可以學精神就好。

## 目的
1. 開發手機APP 不用有兩套驗證及API。
1. 無狀態的API,伺服器更容易水平擴展。
 ex:每增加一台伺服器，系統的效能（performance），也能成比例地增加。
1. 解決Same Site Cookie(產品端才有這問題，平台沒有)

## 風險
1. Seucrity control by develoepr。<br/>

## 舊有的系統對 Session 相依性
1. 登入資訊
1. 登入失敗次數 
1. IP Block 
1. 驗證碼

## 舊有的系統對 Cookie相依性
1. Sticky Cookie 
1. Data Cookie
1. Signal R有用到 Net Forms Authentication (Base on cookie) 
(Connect 時傳入JWT 就好)

## JWT 驗證機制
為了避免Token 被偽造，登入時將token寫進Redis，所有Request的驗證都需要經過redis 驗證。

## JWT 要存那裡

| 解決方案 | 遇到的問題 |
| -------- | -------- |
| localstorage|XSS安全性、手機無痕不能用、舊版手機不能用  |
| local storage 轉存session storage | local storage有相容性問題 |
| redux-state-sync | 要跑EA 技術審核流程，先不考慮 |
| ★ InMemeory | 跨視窗狀態同步時，流程處理有點複雜，但是相容性最好 |

P.S. Cookie 和local Storage  在用戶端都會產生實體檔案，但現在的瀏覽器會加密，是有機會破解，session storage 確實比local storage更安全 ，最好是不落地比較安全。

## JWT的長度
過去的在線人數統計，是依賴Login Table  的SessionId欄位所計算
，長度目前只有100字元，標準的JWT的長度多半超過100 字元，db 相關欄位要跟著調整。

## Refresh Token 跨視窗互搶的問題
Desktop Web 有一個window open 的功能，用來查詢帳戶歷史，對於Angualr app來說是兩個獨立的app，在更新token 時會互搶。

我的做法是子視窗一律不換Token，用Post Message 通知父視窗更新token
並將接下來的Request queue住,直到父視窗 token 換完解鎖，再通知子視窗。
(queue 住後等待超過秒數，透過RX的timeout放掉)

## JWT 踢人的問題
JWT Token 規範中，並沒有明確定義，踢人的邏輯都需要自己去實作
1. Idle(閒置未下單)
1. Token Expired(Token 失效)
1. Double Login (雙重登入)
1. Manual Logout(手動登出)
1. No Logout (未正常登出)
1. Maintenace Kick out (Bo Site 踢人)
這邊踢人的做法是透過清除Redis 註銷token，請Log Kick reason以方便日後追蹤。

## 使JWT更安全的方式
1. 網站必需採HTTPS
1. 縮短Access Token 時間
1. Access Token 挷定 瀏覽器指紋(Device Id)
https://fingerprintjs.com/?fbclid=IwAR1I0nRPyiJJUHosyXa80GwJi45-4tHjxV5uZPnTBks-XT3Kp3-tyi1ln1M
1. 禁止開F12的功能。(需要留後路)
1. 會員登入記錄
1. 挷IP <br/>
客戶端可能切換網路，手機IP 也會跳動，可以搭配系統訊息ip變更需要重新登入。

## Session Cookie 機制並存
上線後，如果發生問題如果要處理很久，希望快速切換回來，這邊有保留，Session Cookie並存的機制。
這邊是透過讀取config ，並由autofac決定要注入Jwt或Session 邏輯。

```
   if (IsJWTAuthentication)
   {
        builder.RegisterType<JWTSessionData>().As<ISessionData>();
        builder.RegisterType<JWTAuthenticationBLL>().As<IAuthenticationBLL>();
   }
   else
   {
        builder.RegisterType<SessionData>().As<ISessionData>();
        builder.RegisterType<AuthenticationBLL>().As<IAuthenticationBLL>();
   }
```

## 大概有多少工作
1. 處理Session相依性
1. 處理Cookie 相依性
1. JWT Token 實作
1. JWT 登入驗證功能
1. 踢人功能
1. Refresh Token
1. API端 Sesssion / Cookie 機制抽換


## 補充

## Https 一定安全?
實際上不見得，下列情境可能會造成 Https 不安全
1. 使用太舊的加密演算法 
1. Library實作加密演算法有bug 
1. CA憑證單位被收買了
1. Private Key流出
1. FBI

## JWT Token 挷定 IP的副作用
客戶端可能切換網路，手機IP 也會跳動，不適合將Token 綁定IP。
應該也是可以的，這其實也是一個合理的行為，只要ba要同意，只要ip變更就得就登出, 並顯示登出原因


## 額外發現
1. Redux dev tool production 沒關閉

---

## 關於本文與作者

本文出自 [Mark Ku's Blog](https://blog.markkulab.net/post/jwt)

授權條款： [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — 轉載或引用請註明作者並附上原文連結

### 關於作者

**[Mark Ku](https://blog.markkulab.net/author/mark-ku)** — Software Solution Provider

- 10+ 年資深軟體工程師，現為 AI 應用 Builder
- 專注大型平台架構設計，從北美電商到AI SaaS訂閱收費系統
- 結合 AI Agent 與自動化，打造高效可演進的產品技術基礎

### 作者開發的免費工具

以下工具皆可免費使用：

- [免費 PDF 簽名工具](https://blog.markkulab.net/tools/pdf-sign): 線上 PDF 簽名工具，瀏覽器內完成手繪、打字、上傳簽名，可拖曳放置、縮放、下載。所有處理都在你的裝置完成，檔案不會上傳。
- [VS Code Refactory](https://blog.markkulab.net/tools/refactory): Refactory 是一款 VS Code 重構擴充套件：34 個重構動作、37 條 code smell 檢查、Code Health 儀表板、18 種語言、534 支測試。懂你的專案慣例：介面放哪、DI 註冊寫在哪、'use client' 該不該加；還會用 git 修改頻率 × 複雜度排出「該先修哪個檔案」，並一鍵把壞味道交給你自己電腦上的 Claude Code 修。免費使用，原始碼不離開你的機器。
- [DB-Kit 資料庫管理工具](https://blog.markkulab.net/tools/db-kit): DB-Kit 是一個用 Tauri + Rust + React 打造的輕量跨平台資料庫管理工具，用單一一致的介面同時管理 MySQL、MariaDB、PostgreSQL、SQL Server、Oracle、SQLite、MongoDB、Redis、Kafka、Elasticsearch 與 RabbitMQ 十一種資料來源：連線密碼以 OS keychain 加密、SSH Tunnel、完整 CRUD、視覺化查詢建構器、多結果集同時顯示、跨連線資料傳輸與比對同步、Excel / CSV 匯入匯出、執行計畫視覺化、ER 圖、排程備份、SQL 壓力測試（p50～p99 延遲百分位）、15 條規則的 SQL 審查、Kafka 訊息瀏覽與監控告警；繁中 / 英文雙語介面，內建 AI 助手（自然語言生成 SQL、AI 審查與調校建議）與命令列工具 dbk。免費開源（MIT），提供 Windows / macOS / Linux 安裝檔。
- [VS Code Super Mermaid](https://blog.markkulab.net/tools/super-mermaid): Super Mermaid 是一款 VS Code 擴充套件：開箱即用的漂亮 Mermaid 圖表，自動上色、即時預覽、滑鼠平移縮放、PNG / SVG 高解析匯出，內建 21 種範本與多種主題。免費開源（MIT）。
- [React Super Mermaid](https://blog.markkulab.net/tools/react-super-mermaid): react-super-mermaid 是一個開源 React 元件庫：一行 <MermaidViewer> 即可渲染漂亮的 Mermaid 圖表，內建 colorful / sketch 主題、平移縮放、圖內搜尋、SVG / PNG 高解析匯出。輕量、SSR 安全、完整 TypeScript 型別。免費開源（MIT）。
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/tools/jira-super-mermaid): Atlassian Forge app：在 Jira issue 與 Confluence 內文直接寫 Mermaid 語法，畫流程圖、時序圖、狀態機與甘特圖。11 種圖表、SVG / PNG 匯出、明暗主題、完整中日韓文字支援。取得 Runs on Atlassian 資格：圖表存在你自己的站台，app 不呼叫任何第三方服務。免費，即將上架 Atlassian Marketplace。
- [Mermaid 線上預覽](https://blog.markkulab.net/tools/mermaid-preview): 在瀏覽器裡寫 Mermaid、即時看圖，整張圖表壓進網址就能分享。免註冊、不上傳伺服器，相容 mermaid.live 的分享連結。
- [React Intl Phone Number](https://blog.markkulab.net/tools/react-intl-phone-number): react-intl-phone-number 是一個開源 React 元件：framework-agnostic、不依賴 antd，提供 E.164 進出、可搜尋國旗 / 國碼下拉、可配置驗證等級（strict / mobile-strict / loose）、可主題化 CSS 與 i18n，電話邏輯由 google-libphonenumber 驅動。輕量、完整 TypeScript 型別。免費開源（MIT）。
- [Uptime Kuma Cluster](https://blog.markkulab.net/tools/uptime-kuma-cluster): 把單機版 Uptime Kuma 改造成高可用叢集：OpenResty + Lua 智慧負載平衡、MariaDB 共享狀態、健康檢查與自動 Failover，附叢集管理 REST API，一行 Docker Compose 啟動。免費開源（MIT）。
- [特教專案](https://blog.markkulab.net/education): 為特殊教育學生製作的學習教材

### 每日 Podcast

- [科技新鮮事](https://blog.markkulab.net/category/tech-news): 每日精選 AI 與科技趨勢，透過語音摘要快速掌握最新技術動態，涵蓋 AI 應用、軟體架構、DevOps 與工程實戰。 — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/category/ai-stock-chat): 每個交易日用 AI 分析台股盤勢，以雙人對話聊當天的盤中觀察與隔日預測。 — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml

### 電子報

[訂閱電子報](https://blog.markkulab.net/subscribe) — 第一時間收到新文章通知，無垃圾信、隨時可取消訂閱。
