Mark Ku's Blog

實作JWT驗證所遇到的問題

對JWT TOKEN 的理解

JWT當初的設計是為了確保在跨組織間安全互相傳遞資料所存在。 但因為JWT無法確保安全性,後來延伸的JWE,但JWE的標準,定義了很多我們不必要的屬性及命名規範,我在想我們應該是可以學精神就好。

目的

  1. 開發手機APP 不用有兩套驗證及API。
  2. 無狀態的API,伺服器更容易水平擴展。 ex:每增加一台伺服器,系統的效能(performance),也能成比例地增加。
  3. 解決Same Site Cookie(產品端才有這問題,平台沒有)

風險

  1. Seucrity control by develoepr。

舊有的系統對 Session 相依性

  1. 登入資訊
  2. 登入失敗次數
  3. IP Block
  4. 驗證碼

舊有的系統對 Cookie相依性

  1. Sticky Cookie
  2. Data Cookie
  3. Signal R有用到 Net Forms Authentication (Base on cookie) (Connect 時傳入JWT 就好)

JWT 驗證機制

為了避免Token 被偽造,登入時將token寫進Redis,所有Request的驗證都需要經過redis 驗證。

JWT 要存那裡

解決方案遇到的問題
localstorageXSS安全性、手機無痕不能用、舊版手機不能用
local storage 轉存session storagelocal 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(閒置未下單)
  2. Token Expired(Token 失效)
  3. Double Login (雙重登入)
  4. Manual Logout(手動登出)
  5. No Logout (未正常登出)
  6. Maintenace Kick out (Bo Site 踢人) 這邊踢人的做法是透過清除Redis 註銷token,請Log Kick reason以方便日後追蹤。

使JWT更安全的方式

  1. 網站必需採HTTPS
  2. 縮短Access Token 時間
  3. Access Token 挷定 瀏覽器指紋(Device Id) https://fingerprintjs.com/?fbclid=IwAR1I0nRPyiJJUHosyXa80GwJi45-4tHjxV5uZPnTBks-XT3Kp3-tyi1ln1M
  4. 禁止開F12的功能。(需要留後路)
  5. 會員登入記錄
  6. 挷IP
    客戶端可能切換網路,手機IP 也會跳動,可以搭配系統訊息ip變更需要重新登入。

上線後,如果發生問題如果要處理很久,希望快速切換回來,這邊有保留,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相依性
  2. 處理Cookie 相依性
  3. JWT Token 實作
  4. JWT 登入驗證功能
  5. 踢人功能
  6. Refresh Token
  7. API端 Sesssion / Cookie 機制抽換

補充

Https 一定安全?

實際上不見得,下列情境可能會造成 Https 不安全

  1. 使用太舊的加密演算法
  2. Library實作加密演算法有bug
  3. CA憑證單位被收買了
  4. Private Key流出
  5. FBI

JWT Token 挷定 IP的副作用

客戶端可能切換網路,手機IP 也會跳動,不適合將Token 綁定IP。 應該也是可以的,這其實也是一個合理的行為,只要ba要同意,只要ip變更就得就登出, 並顯示登出原因

額外發現

  1. Redux dev tool production 沒關閉

作者

Mark Ku

擁有 10+ 年經驗的資深軟體工程師,現為 AI 應用 Builder,專注於大型平台架構與簡化複雜系統設計,從電商系統到訂閱與收費平台,結合 AI Agent、AI 整合與自動化開發,打造高效率且可持續演進的產品技術基礎。閱讀更多

覺得這篇有幫助?

作者做的免費工具、每日 Podcast 與電子報,都在這裡。

Mark Ku · 本文採用 CC BY 4.0 授權,轉載請註明作者並附上原文連結。

留言

訂閱電子報

訂閱後即時收到新文章通知,不錯過任何技術分享。

提交即表示同意接收電子報,隨時可

熱門文章

View all
Mark Ku
··603

Oracle Cloud 永久免費方案 Linux 主機及固定 IP :0 元打造雲端解決方案

Oracle Cloud 永久免費方案 Linux 主機及固定 IP :0 元打造雲端解決方案
Mark Ku
··440

告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南

告別 Postman 收費陷阱!開源 Git 原生 API 測試神器 Bruno 實戰指南
Mark Ku
··323

一款免費開源類似於 Notion 類知識庫系統 — Outline Wiki 佈署與備份全攻略

一款免費開源類似於 Notion 類知識庫系統 — Outline Wiki 佈署與備份全攻略
Mark Ku
··239

打造高效 API 管理平台:從 0 開始部署 Kong Gateway - Part 1

打造高效 API 管理平台:從 0 開始部署 Kong Gateway - Part 1
Mark Ku
··222

在 Ubuntu 上設置 Samba 來共享資料夾,讓 Windows 11 用戶可以存取

在 Ubuntu 上設置 Samba 來共享資料夾,讓 Windows 11 用戶可以存取
Mark Ku
··199

訓練自己的 AI 語音:硬體門檻、開源模型比較與 LoRA 微調

訓練自己的 AI 語音:硬體門檻、開源模型比較與 LoRA 微調
實作JWT驗證所遇到的問題 - Mark Ku's Blog