老司機:非谷歌規模就無需使用JWT?

banq發表於2024-05-28


該文認為:在大多數情況下,您不應使用 JSON Web Tokens (JWT) 作為身份驗證令牌,尤其是你的系統規模沒有達到 Google/Facebook 規模運營時,特別規模是每秒處理少於 10k 個請求情況下更不應該使用JWT。

什麼是JWT
JSON Web Tokens(JWT)是一種用於認證的令牌標準,它包含頭部、負載和簽名。JWT的核心思想是,任何擁有相應驗證金鑰的人都可以驗證負載的真實性,並且沒有被篡改。JWT規範(RFC 7519)建議使用一些眾所周知的註冊宣告名稱,如發行者、受眾、主題、過期時間等。

JWT主要好處

  • 接收者不需要連線到使用者資料庫來驗證令牌的真實性:

在像Google這樣的大型系統中,認證服務可以是一個獨立的服務,像其他服務一樣進行管理和擴充套件,並且是唯一需要訪問集中式使用者資料庫的服務。所有其他服務可以僅依賴JWT中儲存的資訊,而不需要訪問使用者資料庫,這將避免使用者資料庫成為瓶頸。

重新整理令牌
為了實現登出或會話失效,認證令牌應該有一個相當短的生命週期,最多5分鐘。客戶端還會收到第二個令牌,即所謂的重新整理令牌,它可以用來從認證服務請求一個新的認證令牌。這給了認證服務一個機會去查詢使用者資料庫,看看使用者或特定會話是否在此期間被阻止。

重新整理令牌,而不是對令牌進行認證,是一種“真正的”會話性質的令牌:

  • 重新整理令牌代表與認證服務的會話(可以被撤銷)
  • 而認證令牌只是用於最多幾個請求的派生憑據。

從Google的角度來看,這將保持會話活躍的責任委託給了客戶端,即不是Google伺服器的責任。

假設您不是 Google。請檢查以下哪些情況適用於您,如果答案是Yes,就不需要JWT:

  • 您想要實現登出令牌,因此現在您要保留有效 JWT 的允許列表或已撤銷 JWT 的拒絕列表。要檢查這一點,您需要在每次請求時訪問資料庫。
  • 您需要能夠完全阻止使用者,因此您檢查資料庫中的“使用者活躍”標誌。每次請求時您都會訪問資料庫。
  • 您需要在使用者物件和資料庫中的其他物件之間建立額外的關係。每次請求時您都會訪問資料庫。
  • 您的服務會對資料庫中的資料執行任何操作。每次請求都會訪問資料庫。


總結
對於大多數應用程式來說,使用 JWT 作為身份驗證令牌的弊端和複雜性超過了其帶來的好處。

使用 JWT 進行身份驗證的主要問題是:

  1. 由於 JWT 被設計為無狀態的,因此在到期之前撤銷/使令牌無效非常困難。如果令牌被洩露,則可能導致安全風險。
  2. 管理安全簽名/驗證金鑰以及實施 JWT 缺陷解決方法的複雜性增加。
  3. 由於 JWT 的範圍和特性過於廣泛,存在潛在的安全漏洞,從而導致實施錯誤。
  4. JWT 是為不記名令牌認證而設計的,其安全性低於所有權證明令牌。

與使用 JWT 相比,對於大多數應用程式來說,一種更簡單、更安全的方法是使用儲存在資料庫中的不透明會話令牌以及用於實現可擴充套件性的快取層。這可以輕鬆撤銷令牌,降低複雜性並改善安全實踐。

JWT 對於特定用例仍然有用,例如 API 身份驗證或在各方之間安全地傳輸資料,但應該明智地使用它們,並清楚地瞭解它們的侷限性和潛在的安全風險。

在不需要JWT時:

  1. 直接用Web框架提供的常規會話機制即可,這種方式已經經受了時間的考驗。
  2. 如果您需要一些大型系統,使用valkey來儲存會話資料,。這樣,還是使用經過身份驗證的使用者ID來查詢資料庫,但對於未經身份驗證的請求,它可能會更快/使用更少的資源。


網友討論
1、如果只有一個單體網路應用程式作為身份提供者,單體內部做出所有身份驗證,那麼你可能不需要 JWT。
在多個服務間共享會話本身就是一個分散式系統問題,需要注意許多安全問題,而使用令牌可能是一個不錯的選擇。

2、在大多數用例中,隨機令牌就可以了,一切都取決於它如何儲存以及在何處儲存。
但這也意味著你可以將 JWT 用作大多數應用程式的“隨機令牌”,生成它們的成本並不高,並且只在以下情況下使用額外的容量:

  • - 當你想檢查簽名時(例如在到達你的應用層之前拒絕)
  • - 在恢復會話之前儲存您想要的非敏感 base64 資料

建立和處理 JWT 的成本和複雜程度完全取決於您的需要,因此在我看來,它具有足夠的靈活性,可以輕鬆使用且幾乎不會產生任何懲罰。

3、JWT 的優點在於它們會過期,每個快取都有 TTL,因此您只需將條目的 TTL 設定為您正在快取的令牌的到期日期即可,無需每晚手工清理。


4、這篇文章似乎根本沒有提到微服務架構?對我來說,這是使用 JWT 的主要原因。這樣你就可以透過微服務服務到服務呼叫鏈傳遞身份驗證,如果你沒有微服務,那麼就沒有什麼理由使用 JWT了。
單體系統不要使用 JWT,但有很多公司(無論好壞)都使用微服務。

5、JWT 最適合零信任機器對機器身份驗證,在確認請求者身份後,您可能還想授權某些動詞/操作/角色。

6、即使在不及谷歌規模的較小的環境中執行,也應該使用JWT:

  • 1) 您可能不希望應用伺服器直接訪問認證服務或認證資料庫。當敏感資料跨服務共享時,您可能沒有足夠的資源來控制員工對敏感資料的訪問。您可能希望將有限的資源用於對包含最敏感資料的系統進行安全審計,而將這些系統與其他系統分開則會有所幫助。
  • 2)根據您使用的第三方服務,在授權和其他服務之間建立連線可能並不現實,即使建立了連線,延遲也可能會很嚴重,因此您不希望它阻止每個請求。這對於混合環境尤為重要,例如,在主機庫中使用了 20 年的資料庫,其中包含您的使用者資料,以及由顧問在 PaaS 上為您構建的新服務。
  • 3)人們覺得失效JWT令牌是個噩夢,但你只需要授權服務簽署失效令牌並傳遞給面向客戶端的服務,而這些服務只需要在授權令牌的最大 TTL 內保留這些令牌,之後就可以將它們從快取中驅逐。這可能是由於擁有像谷歌這樣的龐大環境,也可能只是一種降低成本的方法,因為你需要按位元組儲存或按雲上的出站請求付費。你可以說,儲存失效資料與儲存會話資料一樣糟糕,但關鍵問題是 "在哪裡?"和 "多長時間?"。
  • 4) 您可能不希望將敏感的使用者資料儲存在您希望託管應用程式的轄區內。這不是公司的大問題,而是取決於您所提供服務的性質。

相關文章