了解 JWT、OAuth 和 Bearer 令牌
當 Web 成為人們可以實際執(zhí)行有意義的任務(如銀行或工作)的地方時,隱含的需求就是對使用服務的人進行身份驗證。
畢竟,我們不能只相信使用這些服務的人使用了它們。必須實施某種方式,讓人們可以證明他們是他們所說的那個人。
最初,這就像用戶名和密碼組合一樣簡單。理論上,您是唯一知道您的密碼的人。
身份鑒權
通常,您會使用您的憑證在網頁上填寫表單,然后點擊提交。您的詳細信息將通過 HTTP 發(fā)送 POST 請求到服務器,服務器將檢查您的密碼是否與存檔的內容匹配,然后向您發(fā)放一個 cookie。
該 Cookie 將包含您的Token,并將與每個后續(xù)請求一起提交,以便服務器知道在每個后續(xù)請求中信任您。
如果需要在會話期間存儲數(shù)據(jù),例如您選擇的數(shù)據(jù)或首選項,則可以將其存儲在session中。有時,這被稱為 sessionizing 您的數(shù)據(jù)。
在用戶session中存儲數(shù)據(jù)是存儲和檢索瞬態(tài)信息的一種簡單且廉價的方法。
不幸的是,這種方法有幾個缺點:
- 將您的用戶名和密碼發(fā)布到服務器,經常發(fā)生在不安全的 HTTP 請求上。在這種情況下,您的用戶名和密碼可以被任何人或您與服務器之間的任何內容直接從 HTTP的POST 請求中讀出
- 將您的密碼(本應是秘密的)發(fā)送到遠程服務器并不是一個好主意。如果遠程服務器遭到入侵,那么不良行為者將可以輕松訪問發(fā)送給他們的這些憑據(jù),然后可以自由地在其他銀行網站或電子郵件提供商上試用這些憑據(jù)。因為密碼經常被重復使用,所以這將非常有效
- 很多時候,密碼會以明文形式存儲,并以這種格式在服務器上進行比較,這對于黑客或其他可以檢索用戶名/密碼組合寶庫的不良行為者來說顯然是一個相當大的蜜罐
至于在用戶的session中存儲數(shù)據(jù),如果有一臺服務器為應用程序提供服務,則此方法有效。當服務器跨越多個服務器時,所有服務器都必須保持其會話同步。
為此,人們設計了許多方法,例如將會話數(shù)據(jù)存儲在數(shù)據(jù)庫服務器上或某種內存存儲中,但從長遠來看,更好的解決方案是簡單地完全刪除會話。
依賴服務器上的可變數(shù)據(jù)存儲不是一個好主意,理想情況下,使用者應該擁有應用程序運行所需的所有信息。
JWT
回到我們最初的例子,當我們看另一個人時,我們可以快速評估我們是否認識他們。根據(jù)我們是否了解他們,我們可以向他們提供有關我們生活和發(fā)生的事情的更多細節(jié)。
但我們不能指望總是能夠看到信任他們的人。有時,我們可以在不見對方的情況下進行信任交換。
例如,當您上班時,您可能有一張刷卡,您可以在讀卡器上刷卡。讀卡器會讀取您的卡,如果卡有效,則通過身份驗證。這更好,因為您不必向任何人透露您的密碼或任何對您來說保密的事情。
我們知道使用讀卡器進入建筑物是安全的,因為信任鏈是完整的。讀卡器是由值得信賴的公司發(fā)行的,您的門禁卡也可能由他們發(fā)行。我們可以把卡帶走,在某個地方存放很長時間,當我們回來的時候,它仍然是值得信賴的。
如果有人打開卡并更改或更改它以試圖給他們更多的訪問權限,他們反而會損壞卡,它就會停止工作。
JWT 有點像這樣。它們由三個獨立元件組成:
- 描述令牌中的信息以及正在使用的加密的標頭
- payload
- 證明 Token 可靠的簽名
計算簽名的算法是 header 和 payload 的加密結果與 secret 相結合。因此,如果header或payload發(fā)生更改,則簽名將無效,并且內容將不受信任。
因此,即使我們在 JWT 中包含數(shù)據(jù)以表明用戶是管理員,只要簽名得到正確驗證,我們就可以確保 JWT 仍然是該事實的正確表示。因為公眾無法訪問我們的簽名密鑰,所以我們可以確定唯一可以頒發(fā)該 JWT 的實體是我們的服務器。
我們可以在 https://jwt.io 這樣的網站上輕松查看 JWT 令牌的內容。
攜帶您的令牌
現(xiàn)在我們有了令牌,下一個問題應該是我們如何將其呈現(xiàn)給服務器。以前的身份驗證方法需要基于 Cookie 的身份驗證。但是,通常使用我們的 JWT 令牌,我們會將它們與受保護的資源一起呈現(xiàn)給服務器,以便我們可以被授予訪問權限。
這意味著在我們的 HTTP 方法(POST、GET 等)中,我們還將包含一個 Authorization 值。它通常如下所示:
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.uXrIhrveuvbR4tD1ULholQObboLVC-wIfJOEVElEzcs
使用此令牌,服務器可以在分析令牌中的聲明之前驗證令牌。但是,索賠包含哪些內容?
聲明只是 JWT 中包含特定令牌信息的字段。它們分為三類:注冊、公共和私有。
已注冊的聲明是可在 JWT 令牌中使用的標準字段。它們不是必需的,但通常會在大多數(shù)代幣中找到。
公共聲明由應用程序定義,并與正在使用的應用程序的數(shù)據(jù)相關。
私有聲明是用于在實現(xiàn)之間共享信息的自定義聲明,但只有涉及的實體知道聲明是什么以及它們的工作原理。
OAuth 2.0 與此有何關系?
我們詳細介紹了什么是 JWT、它們的工作原理以及我們可以信任它們的原因。通常,它們與 OAuth 一起被提及,有時人們會嘗試比較它們或嘗試選擇一個而不是另一個。
但是,它們沒有可比性,而是 OAuth 通常使用 JWT 令牌來傳輸與其相關的信息。由于 JWT 是一種以防篡改方式傳輸重要數(shù)據(jù)的可靠方法,因此它們是在 OAuth 2 中使用的不錯選擇。
例如,OAuth 發(fā)送的 ID 令牌始終作為 JWT 發(fā)送。當同時發(fā)送訪問令牌時,它通常也作為 JWT 發(fā)送。OAuth 使用 JWT 來實現(xiàn)與其相關的各種流。
另一種類型的令牌是 Bearer 令牌,它與 Authorization 標頭中的每個 HTTP 方法一起發(fā)送。它充當安全資源,指示令牌的持有者有權訪問相關資源。因此,請務必僅將 Bearer 令牌發(fā)送到需要它的受保護終端節(jié)點。
OAuth 可以使用任何其他可行的系統(tǒng)來傳輸其令牌,但是因為 JWT 是一個標準,所以這就是正在使用的系統(tǒng)。事實上,OpenID Connect 正在擴展 JWT。
結論
JWT 和 OAuth 是安全的異步 Web 的關鍵部分。正如我們在本文中所看到的,他們不是競爭對手,您也不應該(或您可以)選擇一個而不是另一個。JWT 以 OAuth 的補充能力存在,并且在將可信數(shù)據(jù)從 A 點移動到 B 點方面做得非常出色。