2012-03-13 128 views
0

我想爲我的一個php應用程序提供一個API。我如何防止未經授權的API訪問? 試圖爲每個註冊用戶提供一個API密鑰,但我認爲在與不同域使用時可能會失敗。 簽名驗證或api密鑰驗證背後的想法是什麼。請給我一些建議提前使用PHP簽名或API密鑰驗證

感謝

+0

的可能重複[我該如何處理授權PHP編寫的API(http://stackoverflow.com/questions/7830970/how-do-i-handle-authorization-to-an-api-written- in-php) – deceze 2012-03-13 07:27:25

回答

7

API密鑰可以用來控制查詢速度,如果它們是可見的。這意味着你不會允許每分鐘每個密鑰每分鐘N次請求或類似的事情。他們不是真正的安全手段,而是身份。

現在,你如何確保這個密鑰實際上由它所屬的用戶使用?

這樣做的一種方法是請求籤名。當您通過一系列參數(a = x & b = y ...)傳遞請求時,只會創建一個簽名,只有客戶端和服務器才能創建或驗證。這是通過獲取參數和值並創建它們的MD5或SHA1總和來完成的,將一個祕密變量或鹽添加到字符串中。此變量絕不會在網絡上發送,並且僅通過https通過其管理控制檯對用戶可見。不過,一定要在散列之前按字母順序對參數進行排序!

所以,如果我的參數是:foo=bar&bar=baz,我將整理的參數字典,加上祕密$SECRET='asd32efe32ef2df23',並創建:$sig = md5('bar=baz&foo=bar'.$SECRET);然後可以再補充&sig={$sig}請求。另一端將執行與參數(不包括sig)相同的操作並驗證它。

一個好主意是改變每個會話或每隔一段時間的祕密。這可以通過使用密碼或SSL證書的HTTPS完成。

編輯:你通常添加的一件事使它更安全,是一個遞增的請求id,也通過網絡未加密發送,並用於哈希處理。這可防止具有相同簽名的兩個相同請求,並防止重播攻擊(攻擊者重新發送命令)。當你這樣做,你需要允許在服務器無序請求的一些優雅(即客戶端發送它們的順序,但由於網絡速度的,你可以看到他們爲100,102,101在服務器上)。

+0

簽名本質上與API密鑰完全相同,並提供完全相同的功能(身份確認)。唯一的區別是,在簽名的請求中,API密鑰本身絕不會通過線路發送,從而最大限度地減少泄漏給第三方的可能性。它並沒有改變這個事實,即它只是一個用戶具有的祕密,不透明的標記,它唯一地標識了他。 – deceze 2012-03-13 07:48:35

+0

我認爲API密鑰是所有人都可以使用的開放標記,因爲您不會正常加密每個API調用。這個API就像你的用戶名,因爲你不能傳遞密碼,所以你傳遞了一些基於密碼的祕密,這就是簽名。 – 2012-03-13 09:30:16