26

我想讓用戶使用他們的Facebook ID登錄我的網站,而無需重新加載頁面。這就是我使用Facebook Javascript SDK的原因。該方案描述了使用此SDK的授權流程: enter image description here如何通過Facebook的Javascript SDK安全地授權用戶

在過程結束時,我知道用戶已登錄,並且我知道他們的Facebook ID。然後我可以通過這個ID在我的數據庫中註冊它們,然後讓它們用它來登錄。

但是,這似乎非常不安全。爲了讓我的服務器端腳本知道用戶的ID,我必須通過AJAX發送它。但是,我無法知道它是否是試圖登錄的ID的所有者。任何人都可以使用一個ID(特別是獲取另一個用戶的ID)發送POST請求。

我現在的想法是讓用戶通過JS SDK像往常一樣登錄,通過AJAX發送ID和訪問令牌服務器,然後使用捲曲的PHP腳本,以確保用戶在實際登錄。

這是要走的路,還是我忽略了更好的替代品?

+1

爲什麼你不只是將javascript-sdk與php-sdk結合起來,因爲它看起來你使用php作爲服務器端語言 – TommyBs

回答

24
  1. 你不需要通過AJAX來推動用戶的ID。您應該在服務器端使用包含signed_request的fbsr_ {app_id} cookie。使用FB發佈的'secret'app_secret解析此signed_request以獲取'user_id'。注意:成功解析也表明FB提供的cookie數據沒有被篡改。

  2. 一旦你解析signed_request,你也應該得到'issued_at'時間。檢查這次是否在最近10分鐘內。通過這樣做,您知道登錄請求會在用戶(使用user_id)使用客戶端SDK時觸發您的服務器。 (請參閱:http://developers.facebook.com/roadmap/completed-changes/

  3. 您應該立即將此代碼換成access_token。如果失敗(FB會給你一個類型爲OAuthException的錯誤消息),這意味着在用戶登錄Facebook和獲取登錄請求之間有一個不自然的延遲。

通過步驟#2,您可以阻止使用舊fbsr_Cookie進行攻擊的嘗試。如果用戶(來自user_id)已經有你的賬戶,那麼你可能希望在這裏停下來登錄用戶。但是,可能會出現app_secret可能受到攻擊的情況。爲了照顧這種情況,您應該按照步驟3進行操作,因爲交換的access_token代碼只能在問題的10分鐘內發生和。如果用戶沒有您的網站帳戶,那麼您無論如何都需要步驟#3來使用access_token來檢索其他必要的用戶數據,例如FB中的姓名,電子郵件等。

因此,只有在這10分鐘的安全漏洞內,其他人才能竊取受害者的cookie並嘗試攻擊。如果您對此安全漏洞不滿意,您應該遷移到服務器端身份驗證。該決定取決於您存儲的用戶信息的敏感度。而且你不會妥協任何移動到服務器端的認證,你可以同時繼續使用客戶端方法來處理其他事情。

+0

@exizt我試圖澄清一些觀點。如果這解決了你的問題,你應該接受答案。 – Ethan

+0

我在我的服務器端使用java。我應該爲第一步調用圖API嗎? –

+1

解析cookie是什麼意思?如何使用node.js或ASP.net做到這一點? –

8

通過JS SDK登錄用戶後,將會設置一個包含憑證信息的特殊cookie(如果我是正確的話,用您的密鑰編碼)。此信息可以通過PHP SDK getUser() method使用。

只要您的API(您的ajax端點)與您的應用程序在同一個域中,每當用戶請求您的服務器時,您都應該收到此cookie。

當然,您需要確保Javascript SDK設置正確,並且您使用了cookie: true config option,並且您給了valid channel file。如果這些要求未得到滿足,那麼在IE和Safari中跨域通信和第三方Cookie可能會遇到一些麻煩。

您還可以檢查此相關的問題:A proper approach to FB auth

相關問題