來自:杜亦舒 性能與架構(gòu)

安全是 RESTful web service 的基石,我們主要討論以下3種主要的方法:
- Basic authentication
- Oauth 2.0
- Oauth 2.0 + JWT
1. Basic authentication
這是最古老、最簡單的方法。
形式
username + password + Base64。
工作機(jī)制
假設(shè)一個(gè)用戶要登錄 Facebook 賬號,查看:feed 流、消息、好友、組,這4個(gè)服務(wù)都是獨(dú)立的。
用戶提交用戶名密碼之后,系統(tǒng)驗(yàn)證后允許進(jìn)入,然而系統(tǒng)是不知道其角色和權(quán)限的,例如什么服務(wù)允許訪問。
所以,每次用戶訪問任何服務(wù)時(shí),系統(tǒng)需要再次驗(yàn)證是否允許此次操作,這意味著需要一次對授權(quán)服務(wù)器的額外調(diào)用。例如上面的4個(gè)服務(wù),那么每個(gè)用戶就會(huì)有4次額外調(diào)用。
現(xiàn)在想象每秒我們有 3000 個(gè)用戶訪問,乘以4個(gè)服務(wù),結(jié)果就是每秒 12000 次授權(quán)服務(wù)器調(diào)用。

結(jié)論
可擴(kuò)展性差,有大量的沒有商業(yè)價(jià)值的額外調(diào)用,顯著增加了服務(wù)器的壓力。
2. Oauth 2.0
形式
username + password + access token + expiration token
工作機(jī)制
用戶使用用戶名密碼登錄系統(tǒng)之后,會(huì)收到一對 token,一個(gè) access token 和一個(gè) refresh token。
access token 用于訪問所有服務(wù),過期時(shí),使用 refresh token 產(chǎn)生一對新的 token。
如果一個(gè)用戶每天都進(jìn)入系統(tǒng),token 會(huì)每天更新,不必每次使用用戶名密碼登錄。
refresh token 也有過期周期,過期后需要再次使用用戶名密碼登錄。
Oauth 2.0 用來替換 Basic authentication,有其明顯的優(yōu)勢,例如用戶不必每次都提交用戶名密碼,然而,系統(tǒng)仍然需要調(diào)用授權(quán)服務(wù)器,來檢查 token 所屬用戶能做的操作。
假設(shè)過期時(shí)間是一天,可以大大減少登錄服務(wù)器的負(fù)載,因?yàn)橐粋€(gè)用戶一天只需要登錄驗(yàn)證一次,而不是每次進(jìn)入系統(tǒng)時(shí)都需要。
但是,系統(tǒng)仍然需要去存儲(chǔ)狀態(tài)的地方去驗(yàn)證每個(gè) token,查看用戶的角色。
所以,最后還是需要多次調(diào)用授權(quán)服務(wù)器。

結(jié)論
和 Basic authentication 有同樣的問題,擴(kuò)展性差,授權(quán)服務(wù)器會(huì)有大量負(fù)載。
OAuth 2 + Json Web Tokens
形式
username + password + JSON map + Base64 + private key + expiration date
工作機(jī)制
用戶第一次使用用戶名密碼登錄系統(tǒng)后,系統(tǒng)不僅返回一個(gè) access token,而且還有一個(gè) JSON map,其中包含所有的用戶信息,例如角色和權(quán)限,這些信息是使用 Base64 編碼的,并使用私鑰加密。

在 token 中存儲(chǔ)了狀態(tài)信息,使服務(wù)是無狀態(tài)的。
用戶自己拿著自己的信息,所有信息都在 token 里面,所以就不需要額外的調(diào)用了。
這對減少服務(wù)器的負(fù)載起到了巨大的作用,現(xiàn)在這個(gè)方法在世界范圍內(nèi)被廣泛使用。
結(jié)論
擴(kuò)展性好,非常適合微服務(wù)。
亞馬遜的做法
在用戶創(chuàng)建亞馬遜賬號的時(shí)候,會(huì)生成一個(gè)永久的、超級安全的 access token,需要用戶保護(hù)好。
當(dāng)用戶需要請求亞馬遜的時(shí)候,需要使用這個(gè)私有的 token 對 HTTP header 數(shù)據(jù)進(jìn)行簽名,并添加到 header 中一起發(fā)送過去。
服務(wù)器端,亞馬遜也有用戶的這個(gè)私有 token,接收到用戶的請求后,同樣對 header 進(jìn)行簽名,然后和用戶的簽名進(jìn)行比較,如何相同,則允許訪問。
最大的好處就是只需要發(fā)送一次用戶名密碼,用于獲取 token,而且使用簽名機(jī)制非常安全,不在乎消息被攔截。

翻譯自:
https://medium.com/@yellow/rest-security-basics-f59013850c4e