來自:杜亦舒 性能與架構
安全是 RESTful web service 的基石,我們主要討論以下3種主要的方法:
- Basic authentication
- Oauth 2.0
- Oauth 2.0 + JWT
1. Basic authentication
這是最古老、最簡單的方法。
形式
username + password + Base64。
工作機制
假設一個用戶要登錄 Facebook 賬號,查看:feed 流、消息、好友、組,這4個服務都是獨立的。
用戶提交用戶名密碼之后,系統驗證后允許進入,然而系統是不知道其角色和權限的,例如什么服務允許訪問。
所以,每次用戶訪問任何服務時,系統需要再次驗證是否允許此次操作,這意味著需要一次對授權服務器的額外調用。例如上面的4個服務,那么每個用戶就會有4次額外調用。
現在想象每秒我們有 3000 個用戶訪問,乘以4個服務,結果就是每秒 12000 次授權服務器調用。
結論
可擴展性差,有大量的沒有商業價值的額外調用,顯著增加了服務器的壓力。
2. Oauth 2.0
形式
username + password + access token + expiration token
工作機制
用戶使用用戶名密碼登錄系統之后,會收到一對 token,一個 access token 和一個 refresh token。
access token 用于訪問所有服務,過期時,使用 refresh token 產生一對新的 token。
如果一個用戶每天都進入系統,token 會每天更新,不必每次使用用戶名密碼登錄。
refresh token 也有過期周期,過期后需要再次使用用戶名密碼登錄。
Oauth 2.0 用來替換 Basic authentication,有其明顯的優勢,例如用戶不必每次都提交用戶名密碼,然而,系統仍然需要調用授權服務器,來檢查 token 所屬用戶能做的操作。
假設過期時間是一天,可以大大減少登錄服務器的負載,因為一個用戶一天只需要登錄驗證一次,而不是每次進入系統時都需要。
但是,系統仍然需要去存儲狀態的地方去驗證每個 token,查看用戶的角色。
所以,最后還是需要多次調用授權服務器。
結論
和 Basic authentication 有同樣的問題,擴展性差,授權服務器會有大量負載。
OAuth 2 + Json Web Tokens
形式
username + password + JSON map + Base64 + private key + expiration date
工作機制
用戶第一次使用用戶名密碼登錄系統后,系統不僅返回一個 access token,而且還有一個 JSON map,其中包含所有的用戶信息,例如角色和權限,這些信息是使用 Base64 編碼的,并使用私鑰加密。
在 token 中存儲了狀態信息,使服務是無狀態的。
用戶自己拿著自己的信息,所有信息都在 token 里面,所以就不需要額外的調用了。
這對減少服務器的負載起到了巨大的作用,現在這個方法在世界范圍內被廣泛使用。
結論
擴展性好,非常適合微服務。
亞馬遜的做法
在用戶創建亞馬遜賬號的時候,會生成一個永久的、超級安全的 access token,需要用戶保護好。
當用戶需要請求亞馬遜的時候,需要使用這個私有的 token 對 HTTP header 數據進行簽名,并添加到 header 中一起發送過去。
服務器端,亞馬遜也有用戶的這個私有 token,接收到用戶的請求后,同樣對 header 進行簽名,然后和用戶的簽名進行比較,如何相同,則允許訪問。
最大的好處就是只需要發送一次用戶名密碼,用于獲取 token,而且使用簽名機制非常安全,不在乎消息被攔截。
翻譯自:
https://medium.com/@yellow/rest-security-basics-f59013850c4e