【SSO單點登入】JWT如何防篡改&&主動登出【黑白名單機制】

語言: CN / TW / HK

theme: smartblue highlight: solarized-light


持續創作,加速成長!這是我參與「掘金日新計劃 · 10 月更文挑戰」的第 4 天,點選檢視活動詳情

大家好,我是melo,一名大三後臺練習生,不知不覺練習時間長達一年了!!!

👉本篇速覽

  • JWT殘留的問題
    • 如何防止JWT被篡改?
      • 擴充套件-- 數字簽名
    • 主動登出
      • 白名單機制
      • 黑名單機制
    • 續簽問題
      • OAuth2.0的refresh token重新整理機制

🎈如何防止token被篡改?

假設前端洩露了token,黑客拿到token之後,也沒辦法同時篡改Header 、Payload、 Signature三部分。

這是為什麼呢? 因為Signature部分的加密演算法:HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

即使黑客修改了header,payload,但由於不知道secret,也就沒法生成篡改後,應當對應的Signature。 - 而後服務端校驗的時候,會解析出其中包含的 Header、Payload 以及 Signature 。服務端會根據 Header、Payload、金鑰再次生成一個 Signature。拿新生成的 Signature 和 JWT 中的 Signature 作對比,如果一樣就說明 Header 和 Payload 沒有被修改,不一樣就說明被篡改,校驗不通過。

不過,如果服務端的祕鑰secret也洩露的話,黑客就可以同時篡改 Signature 、Header 、Payload 了。黑客直接修改了 Header 和 Payload 之後,再重新生成一個 Signature 就可以了。

所以祕鑰secret一定保管好,不能洩露出去。JWT 安全的核心在於簽名,簽名安全的核心在祕鑰。

擴充套件 -- 數字簽名

其實就是JWT中的Signature

  1. Bob將原文md5加密後,再用私鑰對md5加密後的結果加密,變成一個sign,一併傳給Pat【用於校驗】
  2. Pat收到後,用公鑰解密,得到原文md5加密後的結果, 再對傳過來的文章進行md5加密,判斷兩個md5的結果是否一致

關鍵就在於,黑客不知道私鑰,也就沒法篡改原文後,生成跟原文對應的sign,兩者對應不上

本文先簡單聊聊數字簽名,具體HTTPS中的應用,以及微信支付如何確保資料安全,我們之後有機會再出一片文章單獨談談

🎈主動登出

上文我們談到,一般登出只需要前端銷燬儲存在客戶端的token即可,但那樣的話,其實token本質上是還能用,一旦洩露了,你的登入狀態就能被別人利用

但jwt又沒辦法主動過期,此時就需要藉助第三方的方式,來讓token“過期”,提到過期,我們很快就想到了Redis。

白名單機制

  1. 白名單機制認證通過時,把JWT存到Redis中。登出時,從快取移除JWT。請求資源新增判斷JWT在快取中是否存在,不存在拒絕訪問。

這種方式和cookie/session機制中的會話失效刪除session基本一致,但同時也違背了JWT的初衷,每次登入,我們都需要儲存token,跟session一樣有記憶體開銷問題

黑名單機制

  1. 黑名單機制登出登入時,快取JWT至Redis,且【快取有效時間設定為JWT的有效期】,請求資源時判斷是否存在快取的黑名單中,存在則拒絕訪問。

白名單和黑名單的實現邏輯差不多,但黑名單不需每次登入都將JWT快取,僅僅在某些特殊場景下需要快取JWT,給伺服器帶來的壓力要遠遠小於白名單的方式。

只有主動登出的場景下,才需要快取JWT 其他情況下如token自動過期,都不需要

黑名單機制,巧妙的解決了儲存的問題,而且儲存量是遠遠小於,大多數情況下,登入狀態都是token自動過期了,而不是使用者主動登出。

因此,相比之下黑名單更討喜~

💠下篇預告

  • 本篇就上篇殘留的兩個jwt安全問題【篡改+虛假登出】展開了解讀,雖然還有很多解決方式和可擴充套件的點,限於篇幅,我們之後再單獨拎出來詳談。
  • 下篇我們重點關注token的續簽問題,並搭配 OAuth2.0 中的refresh token重新整理機制一同食用,敬請期待~

🧿友鏈