2013-10-09 120 views
13

在我的HTTP API中,其中一個端點應該返回一個隨機生成的值,並且該值將與端點的已認證呼叫者相關聯。目前,我有以下結構:空HTTP POST請求或GET請求通過HTTP API生成隨機值

GET http://example.com/random-ticket HTTP/1.1 
Authorization: Basic base64-encoded-basic-auth-value 
Accept: application/json 
Host: example.com 

HTTP/1.1 200 OK 
Cache-Control: no-cache 
Content-Type: application/json; charset=utf-8 
Date: Thu, 03 Oct 2013 07:25:56 GMT 
Content-Length: 59 

{"user-ticket":"Pfa42634e-1a2e-4a7d-84b9-2d5c46a8dd81"} 

發出GET請求以檢索隨機值。但是,HTTP GET calls should be idempotent和我上面的實現不符合該規則。另一方面,我不確定是否可以發出帶有空郵件正文的HTTP POST請求。

什麼是HTTP電子書執行這類操作的正確方法嗎?

回答

15
  • 安全=>是否在狀態的服務器上的一個變化的通話效果。
  • Idempotent =>多個調用是否導致服務器發生相同的更改。

所以,問題不在於返回的數據。相反,它是服務器狀態:因此,如果將此值存儲在服務器上,則會導致狀態發生更改,則不適合GET。否則,如果它是返回的數據,那很好。如果撥打10分鐘,撥打http://stackoverflow.com將返回不同的數據。

讓我們來看另一個例子,時鐘服務它返回當前時間。每次撥打電話時,您都會得到不同的值,但由於時鐘狀態是分開維護的,因此呼叫本身不會導致服務器上的狀態發生變化。所以在這裏使用GET是一個不錯的選擇。

+0

創建資源!=在服務器上存儲值 –

+0

@FilipW我沒有說存儲一個值。它是**改變狀態**。 – Aliostad

+0

謝謝你們。這個答案更具描述性,消除了我所有的困惑。 – tugberk

11

HTTP中絕對沒有禁止使用空的主體的POST。

而且,消息攜帶一個表示,它是body + headers。在你的案例身體是0長度,這很好,並標識用戶的頭。

看到這裏的討論 - http://lists.w3.org/Archives/Public/ietf-http-wg/2010JulSep/0273.html

+0

對不起,我提到了混亂的GET!但問題是這裏沒有提到的服務器狀態是關鍵。 – Aliostad

+0

我認爲OP很清楚他不應該在這裏使用GET,所以我試圖解釋他爲什麼不應該害怕使用POST來代替 –

+0

我不太確定。 – Aliostad

1

在這種情況下,您應該使用POST,因爲通過設計,可以緩存GET調用。關於空崗位,沒有問題。類似的場景也被在討論:POST with empty body,其中一個交提到:

沒有內容長度和沒有身體POST等同於用Content-Length的一個POST:以下0和任何結果,如能完全例如,當你上傳一個空文件時就會發生。資源由URL決定,服務器必須知道如何處理主體,包括是否爲空。我沒有在這裏看到其實這個問題: -/

威利

+2

「GET調用可以被緩存」這是正確的,但取決於您想要實現的數據一致性,即服務器上數據更改的頻率。所以你也可能有GET請求,你不想允許緩存。此外,請考慮一定不要緩存的驗證數據。所以你的緩存參數並不適合這裏。 – brazo

+2

您可以返回適當的緩存標頭。 – Aliostad

4

存在具有與獲得一個隨機數發生器,因爲是沒有存儲服務器的狀態沒有問題。以同樣的方式,你可以有一個計算器接受參數,並在調用GET時添加它們。關於可緩存的問題是一個有趣的問題,但並不真正適用於隨機生成器,因爲本質上的資源沒有被緩存。這仍然不能改變它可以以安全/冪等方式設計的事實。

至於沒有身體的POST,或者甚至在查詢字符串中使用參數,這很好。 POST的關鍵在於它可能會導致服務器發生變化。它不會保證它會,但你不能認爲它不會像GET一樣。無論是否設置了任何內容,都不會改變可能發生變化的事實。例如想象一個虛構的資源「\ counter \ increment」。每次發佈它時,都會導致\ counter增加。我沒有發送任何有效負載,但是我導致了服務器狀態的變化,因此它應該是POST或PUT。