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