iT邦幫忙

2024 iThome 鐵人賽

DAY 24
0
自我挑戰組

技術隨筆系列 第 27

透過 Protobuf 改善 JWT 傳輸性能是可行的嗎?

  • 分享至 

  • xImage
  •  

曾經構想過的技術提案,大致說明起因,嘗試估算能夠帶來的效益,最後提出衝突點、可行方案和結論

起因

JWT 通常包含三個部分:Header、Payload、和 Signature。這三個部分經過 Base64 編碼後形成最終的 JWT。儘管 JWT 非常適合無狀態的身份驗證系統,但它的結構經常會變得相對臃腫,特別是在需要攜帶較多的用戶信息時。如果應用對數據體積敏感,JWT 的大小成為一個潛在的問題。

構想是使用 Protobuf 精簡 JWT 的內容,透過 Protobuf 定義二進位傳輸格式,可以有效減緩 JWT 內 Base64 編碼造成的數據膨脹

估算性能改善

假設每天 500 位活躍用戶,每個用戶每天進行 10 次 JWT 交換操作(例如登入、API 請求等)

  • 標準 JWT:典型的 JWT 包含 header、payload 和 signature,其中 payload 部分通常包含用戶 ID、角色、權限等信息。假設這些信息加起來通常有 300-500 位元組,經過 Base64 編碼後,JWT 的總大小大約會是 450-700 位元組。

  • 使用 Protobuf 優化後的大小:Protobuf 是一種高效的二進制序列化格式。假設同樣的 payload 信息通過 Protobuf 編碼後可以壓縮到大約 150-250 位元組,最終 JWT 的總大小可以降低到 200-350 位元組。

估算每日的總流量

  • 標準 JWT 的流量:500 位用戶 * 10 次 * 500 位元組(取中位數) = 2,500,000 位元組(約 2.5 MB)。
  • Protobuf 優化後的流量:500 位用戶 * 10 次 * 275 位元組(取中位數) = 1,375,000 位元組(約 1.38 MB)。

這樣的流量節省大約是 45%。隨著用戶量增加或使用頻率增高,這個優化的效果會更加明顯。

衝突點

  1. HTTP header 限制與格式規範:HTTP headers 是設計來傳遞文本數據的,JWT 使用 Base64 編碼可以轉換為可讀文本,而二進制數據則不符合 HTTP header 的傳遞格式規範。若直接將二進制的 Protobuf 內容放入 Authorization header,這會破壞原本的 HTTP header 規範。

  2. 安全性問題:如果將 Protobuf 編碼的認證信息移到其他不符合 Authorization 的 header 中,比如自定義的 header,這樣可能會導致安全問題,因為許多系統和中介(如代理、CDN)對 Authorization header 有特定的處理邏輯和保護措施,而其他自定義 header 可能不會受到同樣的關注與保護。

可行的方案

  1. 維持使用 JWT 結構,但精簡 Payload 內容,無法精簡的 Payload 部分轉移至其他 API 取得
  2. 把 JWT 轉成 Protobuf,不在 Authorization header 使用,需要重新定義身份認證的方式

結論

使用 Protobuf 是可行的,但身份認證的方式會需要重新調整


上一篇
Laravel 11 升級指南 & 版本管理策略
下一篇
PHP 未來可能支援原生的事件迴圈嗎?
系列文
技術隨筆30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言