2014-01-07 125 views
2

作爲服務器REST API設計的一部分我正在考慮我希望能夠返回以客戶端授權級別爲條件的數據。建議完成此操作的方式並將其稱爲一個API?更具體地講,考慮下面的例子一本書訪問API:授權相關的REST API

HTTP GET /library/books/{book-name} 
  1. 任何驗證的客戶端應該能夠獲得(JSON)數據的書,如:

    { 「書」 : {「書的名字」:「ABC」,「作家」:「某人」}}

  2. 但具體的子集驗證客戶端也應該能夠獲得:

    { 「書」: { 「書的名字」: 「ABC」, 「作家」: 「一個人」}, 「私人信息」: { 「本書狀態」: 「對貸款」 ,「價格」:「$ 20」} }

對於給定的書,任何合適的授權客戶端也可以通過直接的HTTP訪問「私人信息」 GET /庫/書籍/ {書籍名稱} /私人信息。

現在,假設有一個合適的客戶端身份驗證方案,我不禁想到上面的HTTP GET/library/books/{book-name}實際上看起來像兩個API,通過服務器上的授權狀態進行區分關於認證。這似乎不是很RESTful。

也許最好讓所有的基本GET書API都沒有任何「私人信息」,同時讓授權的客戶端只能訪問私人信息URI並將403返回給所有其他人?

這種類型的條件數據訪問通常如何使用REST API進行處理?

回答

1

你的方法沒有什麼天生的錯誤 - 根據用戶的授權隱藏信息是很有意義的。 REST對此沒有任何說明 - 資源的表示可能取決於用戶授權,月相或其他任何你能想到的東西。

如果將私人信息提取到單獨的資源,則雖然可以改進緩存。在這種情況下,您可能會在/ library/books/{book-name}中擁有一些相當靜態的內容,這些內容可以在客戶端進行緩存。那麼你會有/圖書館/書籍/ {書名} /私人信息,這將更加不穩定和用戶依賴 - 因此不容易超過。

建立在此您可以在原有資源的鏈接,私人信息:

{ 
    Title: "A book", 
    Author: "...", 
    PrivateInfoLink: "http://your-api.com/library/books/{book-name}/private-info" 
} 

這樣做的好處是雙重的:

1)服務器可以離開了鏈接如果客戶端無法訪問私人信息並因此將客戶從不必要的往返節省到(不)獲取私人信息。

2)服務器可以自由更改私人信息的URL,如果它稍後需要(它可能是例如基於用戶授權的不同的URL)。

如果您想了解更多關於超媒體的好處,那就試試這個:http://soabits.blogspot.dk/2013/12/selling-benefits-of-hypermedia.html

+0

謝謝,這是非常有用的 – void4

1

我最近回答了類似的問題。你可以找到我的答案here

底線是:您應該嘗試將業務邏輯與授權邏輯分開,始終爲。這意味着您想要將您的授權外部化。有幾種方法可以做到這一點。

你的具體情況,想象敏感字段列表中,只有客戶的一個子集可以查看隨時間的變化,這將潛在地需要你的API的重寫。如果您將授權邏輯從業務邏輯(API)中分離出來,那麼您可以輕鬆更新授權邏輯,而無需重寫任何代碼。這就是所謂的外部化授權管理(請參閱有關該主題的偉大Gartner的paper)。

正如我一天到一天的工作的一部分,我幫使用XACML客戶安全的API和Web服務。最好的做法是始終保持關注獨立。

+0

非常有用的觀察,謝謝。這似乎得出結論:分開私人信息資源並預先訪問該資源是在從頭開始設計這種洞察時更好的做事方式。現在假設,我們正在處理一個現有的API,其授權邏輯是要提供(例如提供{私人信息}作爲混淆的數據非authrz。客戶端)。我想從處理程序內調用授權框架也是可能的。當然,需要重新編寫服務器代碼,但API仍然保持不變。思考? – void4