REST 是一種現(xiàn)代架構(gòu)風(fēng)格,它定義了一種設(shè)計(jì) Web 服務(wù)的新方法。和之前的 HTTP 以及 SOA 不同,它不是一個(gè)協(xié)議(即:一套嚴(yán)格的規(guī)則),而是一些關(guān)于 Web 服務(wù)應(yīng)該如何相互通信的一些建議和最佳實(shí)踐。按照 REST 最佳實(shí)踐開(kāi)發(fā)的服務(wù)被稱(chēng)為 “RESTful Web 服務(wù)”。
安全性是 RESTful 服務(wù)的基石。啟用它的方法之一是盡可能內(nèi)置用戶(hù)身份驗(yàn)證和授權(quán)機(jī)制。
在 RESTful 服務(wù)中實(shí)現(xiàn)用戶(hù)身份驗(yàn)證和授權(quán)的方法有很多。我們今天要講的主要方法(或標(biāo)準(zhǔn))有:
- Basic 認(rèn)證
- OAuth 2.0
- OAuth 2.0 + JWT
為了讓我們的討論更加具體,假設(shè)我們的后端程序有微服務(wù),并且每個(gè)用戶(hù)請(qǐng)求時(shí),必須調(diào)用后端的幾個(gè)服務(wù)來(lái)返回請(qǐng)求的數(shù)據(jù)。所以,我們將不僅從安全性問(wèn)題方面,而且在它們產(chǎn)生的額外流量和服務(wù)器負(fù)載的背景下檢查每個(gè)標(biāo)準(zhǔn)。下面開(kāi)始吧…
Basic 認(rèn)證
最古老也是最簡(jiǎn)單的標(biāo)準(zhǔn)。
看起來(lái)像: 用戶(hù)名 + 密碼 + Base64(對(duì)用戶(hù)名和密碼做哈希的基礎(chǔ)算法)。
工作原理:加入有人嘗試登錄用戶(hù)的 Fackbook 賬戶(hù),去訪問(wèn)他的消息、歷史記錄、群組信息,這些都是獨(dú)立的服務(wù)。當(dāng)用戶(hù)輸入用戶(hù)名和密碼后,系統(tǒng)會(huì)允許登錄。但是,默認(rèn)情況下,系統(tǒng)不知道用戶(hù)的角色和權(quán)限是什么,他們可以訪問(wèn)哪些服務(wù)等等。
所以每次用戶(hù)嘗試訪問(wèn)任何一個(gè)服務(wù)的時(shí)候,系統(tǒng)都應(yīng)該再次驗(yàn)證是否允許執(zhí)行這個(gè)操作,這意味著需要對(duì)身份驗(yàn)證進(jìn)行額外的調(diào)用。就我們的示例中有四個(gè)服務(wù)而言,在這種情況下,每個(gè)用戶(hù)將有四個(gè)額外的調(diào)用。
現(xiàn)在假設(shè)每秒有 3k 個(gè)請(qǐng)求,在 Facebook 的系統(tǒng)中每秒 300k 請(qǐng)求更現(xiàn)實(shí)。將這請(qǐng)求乘以四,結(jié)果是每秒要向服務(wù)器發(fā)出 12k 次調(diào)用。

總結(jié):可伸縮性差,大量的額外流量(額外調(diào)用)沒(méi)有帶來(lái)業(yè)務(wù)價(jià)值,服務(wù)器的負(fù)載很大。
OAuth 2.0
看起來(lái)像:用戶(hù)名 + 密碼 + 訪問(wèn)令牌 + 過(guò)期令牌
工作原理:OAuth 2.0 標(biāo)準(zhǔn)的核心思想是,用戶(hù)使用用戶(hù)名和密碼登錄系統(tǒng)后,客戶(hù)端(用戶(hù)訪問(wèn)系統(tǒng)的設(shè)備)會(huì)收到一對(duì)令牌,這是一個(gè)訪問(wèn)權(quán)限令牌和刷新令牌。
訪問(wèn)令牌用于訪問(wèn)系統(tǒng)中的所有服務(wù)。到期后,系統(tǒng)使用刷新令牌生成一對(duì)新的令牌。所以,如果用戶(hù)每天都進(jìn)入系統(tǒng),令牌也會(huì)每天更新,不需要每次都用用戶(hù)名和密碼登錄系統(tǒng)。刷新令牌也有它的過(guò)期時(shí)間(雖然它比訪問(wèn)令牌長(zhǎng)得多),如果一個(gè)用戶(hù)一年沒(méi)有進(jìn)入系統(tǒng),那么很可能會(huì)被要求再次輸入用戶(hù)名和密碼。
OAuth 2.0 標(biāo)準(zhǔn)取代了基本的身份驗(yàn)證方法,它具有一定的優(yōu)勢(shì),例如用戶(hù)每次想要進(jìn)入系統(tǒng)時(shí)不用輸入用戶(hù)名和密碼。但是,系統(tǒng)仍然需要調(diào)用身份驗(yàn)證服務(wù)器,就像使用基本身份驗(yàn)證方法時(shí)一樣,以檢查擁有該令牌的用戶(hù)有權(quán)限做什么。
假設(shè)有效期是一天。這意味著登錄服務(wù)器上的負(fù)載要少得多,因?yàn)橛脩?hù)每天只需要輸入一次憑證,而不是每次都要進(jìn)入系統(tǒng)。但是,系統(tǒng)仍需要驗(yàn)證每個(gè)令牌并檢查用戶(hù)角色的存儲(chǔ)狀態(tài)。所以我們最終還要調(diào)用身份驗(yàn)證服務(wù)器。

總結(jié):和 Basic 驗(yàn)證有相同的問(wèn)題 - 可伸縮性差,身份驗(yàn)證服務(wù)器負(fù)載較高。
OAuth2 + JSON Web 令牌
看起來(lái)像:用戶(hù)名 + 密碼 + JSON數(shù)據(jù) + Base64 + 私鑰 + 到期日期
工作原理:當(dāng)用戶(hù)第一次使用用戶(hù)名和密碼登錄系統(tǒng)時(shí),系統(tǒng)不僅會(huì)返回一個(gè)訪問(wèn)令牌(只是一個(gè)字符串),而是一個(gè)包含所有用戶(hù)信息的 JSON 對(duì)象,比如角色和權(quán)限,使用 Base64 進(jìn)行編碼并使用私鑰簽名。下圖是它在沒(méi)有編碼的情況下的樣子:

看起來(lái)很可怕,但這確實(shí)有效!主要區(qū)別在于我們可以在令牌中存儲(chǔ)狀態(tài),而服務(wù)保持無(wú)狀態(tài)。這意味著用戶(hù)自己擁有自己的信息,不需要額外的調(diào)用來(lái)檢查它,因?yàn)樗械膬?nèi)容都在令牌里。這對(duì)于減少服務(wù)器負(fù)載方面是一個(gè)很大的優(yōu)勢(shì)。這個(gè)標(biāo)準(zhǔn)在世界范圍內(nèi)得到廣泛應(yīng)用。
總結(jié):良好的可伸縮性,可以和微服務(wù)一起工作。
新玩意:亞馬遜簽名方式
一種全新的,奇特的方法,稱(chēng)為 HTTP 簽名,亞馬遜是目前使用它的大廠之一。
它的思路是,當(dāng)你創(chuàng)建亞馬遜帳戶(hù)的時(shí)候,會(huì)生成一個(gè)永久的、非常安全的訪問(wèn)令牌,你要非常小心地存儲(chǔ)起來(lái)并且不要給任何人顯示。當(dāng)你要從 Amazon 請(qǐng)求某些資源時(shí),你可以獲取到所有相關(guān)的 http 頭信息,使用這個(gè)私鑰對(duì)其進(jìn)行簽名,然后將簽名的字符串作為 header 發(fā)送。
在服務(wù)器端,亞馬遜也有你的訪問(wèn)密鑰。它們接下來(lái)做什么?只需要使用你的 http 頭信息和這個(gè)密鑰進(jìn)行簽名。然后將簽名字符串和你作為簽名的字符串進(jìn)行比較;如果相同那么就知道你是誰(shuí)。
最大的好處是你只需要發(fā)送一次用戶(hù)名和密碼 - 就可以獲得令牌。至于使用私鑰簽名的 header 信息,基本上沒(méi)有機(jī)會(huì)對(duì)它們進(jìn)行編碼。就算有人截獲了信息——誰(shuí)在乎呢 ;)