2012-01-18 37 views
20

我知道發佈了許多類似的問題,但沒有一個引用HTML/javascript應用程序,用戶可以在其中訪問代碼。如何在AJAX應用程序中保護私有REST API

我有一個寫在nodejs中的私有REST API。它是私人的,因爲它的唯一目的是服務我的HTML5客戶端應用程序(Chrome應用程序和Adobe Air應用程序)。所以API密鑰不是一個好的解決方案,因爲任何用戶都可以看到JavaScript代碼。

我想避免機器人在我的服務器上創建帳戶並佔用我的資源。

有什麼辦法來實現這個嗎?

+2

我不確定是否有任何答案滿足您的問題。請分享你如何處理你所描述的問題。我正在構建可用於未註冊用戶的基於REST + AJAX的Web應用程序。和你一樣,我想保護機器人的資源。 – 2012-04-14 17:28:44

+0

從邏輯上說,真正無法使API真正成爲私人的,如果它是從任何人都可以查看源代碼和/或監視發送到服務器的數據的網頁調用的。爲了抓住機器人,你有像Captcha這樣的常用技巧,但最終你需要後端支持(WAFs,快速自動擴展等)來處理自動DDOS類型攻擊的可能性。只要您儘可能早地檢測到可能的DDOS攻擊(在進行數據庫連接之前等),處理漫遊器試圖首先下載頁面就沒有什麼不同了。 – 2017-11-16 20:25:11

回答

15

API密鑰是一個體面的解決方案,特別是如果您需要對API密鑰的請求源進行約束時;如果原始網絡請求來自授權來源(例如您的私人網域),則認爲您只應接受API密鑰。如果網絡請求來自未經授權的域,則可以拒絕處理請求。

您可以通過使用專門的編碼方案(如基於散列的消息認證碼(HMAC))來提高此機制的安全性。以下資源說明了這種機制明確:

http://cloud.dzone.com/news/using-api-keys-effectively

+2

觀察API密鑰解決方案適用於數十種其他API(包括Google地圖,Flickr,Facebook等)也很重要。訣竅在於實施。 – 2012-01-18 23:13:10

+0

我無法控制我的用戶來自哪裏,這是一個公共應用程序。谷歌地圖,Flickr等使用API​​密鑰,但我不確定他們是否擔心使用密鑰的人。我認爲我可以複製並使用任何Google地圖密鑰(尚未嘗試過)。 – aartiles 2012-01-18 23:30:18

+0

您不能簡單地複製Google Maps API密鑰並將其用於其他域,因爲Google Maps API會將每個生成的API密鑰綁定到特定的域類(即.mydomain.com),並且每一個進入的請求都會針對引用URL以及在API密鑰中編碼的其他信息。再次,典型的編碼機制是HMAC。否則API密鑰將無用。 – 2012-01-19 01:51:26

1

你想要做的就是採用相互認證的SSL,讓您的服務器將只接受來自您的應用程序的傳入連接,你的應用程序將只與您的服務器通信什麼。

這是高層次的方法。創建一個自簽名服務器SSL證書並部署到您的Web服務器上。如果您使用Android,則可以使用Android SDK附帶的keytool來實現此目的;如果您使用的是其他應用平臺,那麼也存在類似的工具。然後創建一個自簽名客戶端,並將其作爲資源部署在您的應用程序中的一個自定義密鑰庫中(keytool也會生成這個)。將服務器配置爲需要客戶端SSL身份驗證,並僅接受您生成的客戶端證書。配置客戶端使用該客戶端證書來標識自身,並且只接受您在服務器上安裝的那一部分服務器端證書。

如果您的應用程序以外的某個人/某個人嘗試連接到您的服務器,則SSL連接將不會被創建,因爲服務器將拒絕未顯示您已包含在您的應用程序中的客戶端證書的傳入SSL連接。

這是一個比這裏保證的更長的答案。我會建議分階段進行這項工作,因爲網上有關於如何處理Android中的自簽名SSL證書(我不太熟悉如何在其他移動平臺上執行此操作的證書)的資源,無論是服務器端還是客戶端。在O'Reilly出版的我的書「Android應用安全平臺」中也有一篇完整的介紹。

+0

我的網絡應用程序是純粹的JavaScript和HTML,而不是android – aartiles 2012-01-19 10:44:50

+0

而這種方法仍然有效。在您的應用程序的Web服務器與您希望與之通信的任何客戶端之間實施相互授權SSL。 – jeffsix 2012-01-19 13:47:56

+0

如何爲標準網絡瀏覽器做到這一點?讓我們說Google Chrome。 – aartiles 2012-01-19 17:09:16