1. 程式人生 > >restful架構風格設計準則(五)用戶認證和session管理

restful架構風格設計準則(五)用戶認證和session管理

好的 困難 是否 ica 過程 集成 設計 管理服務器 系統

讀書筆記,原文鏈接:http://www.cnblogs.com/loveis715/p/4669091.html,感謝作者!

Authentication

  其實在上一節中,我們已經提出了無狀態約束給REST實現帶來的麻煩:用戶的狀態是需要全部保存在客戶端的。當用戶需要執行某個操作的時候,其需要將所有的執行該請求所需要的信息添加到請求中。該請求將可能被REST服務集群中的任意服務器處理,而不需要擔心該服務器中是否存有用戶相關的狀態。

  但是在現有的各種基於HTTP的Web服務中,我們常常使用會話來管理用戶狀態,至少是用戶的登陸狀態。因此,REST系統的無狀態約束實際上並不是一個對傳統用戶登錄功能友好的約束:在傳統登陸過程中,其本身就是通過用戶所提供的用戶名和密碼等在服務端創建一個用戶的登陸狀態,而REST的無狀態約束為了橫向擴展性卻不想要這種狀態。而這也就是為基於HTTP的REST服務添加身份驗證功能的困難之處。

  為了解決該問題,最為經典也最符合REST規範的實現是在每次發送請求的時候都將用戶的用戶名和密碼都發送給服務器。而服務器將根據請求中的用戶名和密碼調用登陸服務,以從該服務中得到用戶所對應的Identity和其所具有的權限。接下來,在REST服務中根據用戶的權限來訪問資源。

技術分享

  這裏有一個問題就是登陸的性能。隨著系統當前的加密算法越來越復雜,登陸已經不再是一個輕量級的操作。因此用戶所發送的每次請求都要求一次登陸對於整個系統而言就是一個巨大的瓶頸。

  在當前,解決該問題的方法主要是一個獨立的緩存系統,如整個集群唯一的登陸服務器。但是緩存系統本身所存儲的仍然是用戶的登陸狀態。因此該解決方案將仍然輕微地違反了REST的無狀態約束。

  還有一個類似的方法是通過添加一個代理來完成的。該代理會完成用戶的登陸並獲得該用戶所擁有的權限。接下來,該代理會將與狀態有關的信息從請求中刪除,並添加用戶的權限信息。在經過了這種處理之後,這些請求就可以轉發到其後的各個服務器上了。轉發目的地所在的服務器則會假設所有傳入的請求都是合法的並直接對這些請求進行處理。

技術分享

  可以看到,無論是一個獨立的登陸服務器還是為整個集群添加一個代理,系統中都將有一個地方保留了用戶的登陸狀態。這實際上和在集群中對會話集中進行管理並沒有什麽不同。也就是說,我們所嘗試的通過禁止使用會話來達成完全的無狀態並不現實。因此在一個基於HTTP的REST服務中,為登陸功能使用集中管理的會話是合理的。

  既然我們放松了對REST系統的無狀態約束,那麽一個REST系統所可以使用的登陸機制將主要分為以下兩種:

  1. 基於HTTPS的Basic Access Authentication

其好處是其易於實現,而且主流的瀏覽器都提供了對該功能的支持。但是由於登陸窗口都是由瀏覽器所提供的,因此其與產品外觀有很大不同。除此之外,瀏覽器都沒有提供登出的功能,也沒有提供找回密碼等功能。

  2. 基於Cookie及Session的管理

在使用Cookie來管理用戶的註冊狀態的時候,其實際上就是將服務端所返回的Cookie在每次發送請求的時候添加到請求中。雖然說這個Cookie並非存儲了用戶應用的狀態,但是其實際存儲了用戶的登陸狀態。因此客戶端的角度來講,由服務端管理的Session並不符合REST所倡導的無狀態的要求。

  可以說,上面的兩種方法各有優劣。可能第二種方法從客戶端的角度看來並不是RESTful的,但是其優勢則在於很多類庫都直接提供了對該功能的支持,從而簡化了會話管理服務器的實現。

  在這裏順便提一句,如果項目足夠大,將一些SSO產品集成到服務中也是不錯的選擇。

restful架構風格設計準則(五)用戶認證和session管理