2016-12-29 41 views
3

我正在構建一個節點/後端快遞。我想創建一個只能用於我的reactjs前端(私有API)的API。保護我的API只適用於我的前端

想象一下,如果這是一個電子商務網站,我的用戶將瀏覽產品,然後選擇要購買的產品,並在訂購時可能會或可能不會登錄。

確保我的API僅適用於reactjs前端的最佳做法是什麼?

當用戶決定登錄或者他們仍然是客人時會發生什麼?

+0

有你之前沒有使用過快遞?你可以像app.get('some/route/here',authHandlerHere,requestHandlerHere)那樣鏈接多個處理程序;''你的認證處理程序可以做類似'req.isAuthenticated()的事情? next():res.sendStatus(401);' –

+0

這是至少兩個問題,在任何情況下都過於寬泛。閱讀Express,PassportJS上的文檔以瞭解路由和身份驗證,並查找跨站點請求僞造防護。然後在這裏發佈代碼,你不會得到它的工作。 – Paul

回答

-1

所以做的一種方式在向你的服務器發送任何AJAX請求的同時,發送一個頭部,其中包含諸如apiKey的某個鍵:「一些鍵」。在服務器中,只要您收到它並驗證您的反應應用程序獲得服務的域。如果不是,你不需要回應。就像

app.get('/route', function(req, res) { 
    if(req.headers.apiKey == "some key) // respond with success 
    // respond with 401 Forbidden 
}); 

所以任何命中服務器的請求應該有apiKey爲了使我工作。

+0

這是一個相當差和不完整的例子。按照書面方式竊取API密鑰也非常簡單。 – Paul

2

應用CORS - 服務器指定允許請求您的API的域。

它是如何工作的?

  1. 客戶端向服務器發送特殊的「預檢」請求(OPTIONS方法),詢問域請求是否來自允許的域。它還詢問請求方法是否OKAY(您可以允許GET,但拒絕POST,...)。
  2. 服務器決定是否允許或拒絕請求。它以「OK」響應作出響應並設置特殊的頭部,告訴哪些域/請求方法是允許的。
  3. 如果允許客戶端查詢您的API,它執行預期的要求,或撈出...

客戶那些尊重CORS(瀏覽器做)會(或不會被拒絕,如果)能連接。如果客戶端忽略CORS(REST客戶端,CLI工具,...),這將能夠連接不管是什麼...

不過,需要簽署請求(授權)

0

所以,這可能是一個稍冗長的答案 - 但你已經發布了一個相當有趣和重要的問題。

作爲一個大部分時間都在使用Node和Python編寫安全庫來處理這種事情的人,我想我會跳到這裏。

您希望用來保護您的React應用程序和後端API的協議是OAuth2密碼授權流程。它在理論上的工作方式非常簡單。

在您的React應用程序中,您收集用戶的用戶名/密碼(如果這是您構建應用程序的方式,那麼也可以是電子郵件/密碼)。

然後您發送POST請求到後端的API,它看起來是這樣的:

POST api.myapp.com/oauth/token 

grant_type=password&username=USERNAME&password=PASSWORD 

確保您發佈到服務器時使用application/x-www-form-urlencoded內容類型。

然後,您的服務器將接收此請求,通過OAuth2庫運行它,並生成兩個令牌:以及Access和Refresh令牌。

一旦你的服務器API生成了令牌,你就會將這些令牌存儲在一個cookie中,然後由用戶的瀏覽器存儲這些令牌。

從這裏開始:所有東西都應該是自動的。當您的React服務器向後端發出API請求時,瀏覽器將通過包含這兩個令牌的cookie自動識別用戶。

你需要使用的OAuth2庫服務器端,因爲這將處理喜歡的東西:

  • 生成令牌。
  • 當刷新標記到期時交換新標記。
  • 基於令牌標識用戶。
  • 撤銷令牌,如果他們受到損害等

有相當多很多吧,但是這是基本的,高層次的想法。

你會注意到:這裏沒有涉及到API密鑰。當您使用不受信任的環境(例如:移動應用程序或客戶端JavaScript應用程序)時,完全不安全存儲永久API令牌 - 原因是它們可以輕鬆從源代碼或JavaScript中提取。

使用上面提到的,而不是流是安全得多,因爲你得到了很多的保護:

  • 存儲在不安全的位置沒有永遠的憑據。
  • 短命令令牌用作標識符。這些隨時間推移而旋轉。
  • 令牌存儲在Javascript無法訪問的cookie中。這意味着網絡曝光的風險較小。
  • 密碼只能更換一次,在會話持續時間 - 這意味着更少的敏感信息會在導線不經常=)

總之:希望這有助於!

而且,如果您正在尋找一些工具,任何oauth庫(服務器端)都應該幫助您解決這個問題。如果您正在尋找可以爲您做到這一點的服務,您可能需要查看我工作的產品(Stormpath)。這是一項付費服務​​,但代表您處理這種複雜性。

+0

OAuth如何保護您的API不被您的控制域訪問? – Andreyco

+0

它沒有。但是,很多人做的是創建應用程序ID並將其分配給每個白名單中的應用程序。這樣,您可以擁有一種非常天真的「保護」形式,但只允許來自列入白名單的應用程序ID的請求(即使攻擊者可以輕鬆找到此號碼,但它提供了進入的障礙)。 – rdegges

+0

感謝您提供上述信息。這非常有用。 –

1

這個用例很有意思,我認爲很多電子商務網站都有問題。我正在研究的product實際上已經和那些試圖在移動領域處理這類事情的公司進行了一些對話。用戶登錄可用於告訴您誰在使用API​​,但如果您不想強制用戶擁有用戶名/登錄名,則必須搜索其他解決方案。你似乎想要的是一種識別什麼軟件正試圖使用​​你的API的方法。

有一對夫婦的是通常用於解決這個問題簡單的方法:

嵌入的祕密

您可以添加一個密鑰對您的應用程序,並要求任何訪問API標識本身使用密鑰。人們會告訴你不要這樣做,因爲提取密鑰非常容易。這是事實,但是在保證所有安全性的情況下,需要進行成本/收益分析,以評估您希望保護API的工作量。與JavaScript的問題是,它不是很容易混淆或隱藏祕密,因爲所有的源代碼就在那裏。

如果你正在考慮一個環境,你可以選擇其他的語言選擇,那麼你可以做更多的事情來混淆你的應用程序的祕密(比如在Android中使用NDK)。雖然Javascript很困難。

使用API​​密鑰記住的重要事情是,您不應該以清晰的方式傳輸它。這樣偷取真的很容易。相反,您可以使用密鑰對API流量進行簽名,以便服務器可以驗證請求是否來自具有密鑰並知道如何簽名的請求。

限速

雖然不是真正的問題,這取決於你正在努力實現這是一種選擇什麼解決方案。如果您擔心來自其他應用程序的大量請求,則可以將限制級別設置爲高於真正應用程序的級別,並且如果請求太多,您可以通過IP地址進一步阻止或限制速度。

相關問題