我想如果我們使用REST或圖形API調用Facebook,我們會知道它是否是假的,因爲它會回來說虛假的會話/ auth_token/access_token。但是如果我們顯示自己的數據庫信息(例如用戶的「最喜歡的產品列表」),那麼我們不會打電話給Facebook,而是顯示我們的數據庫的數據。我們如何知道它確實是用戶,而不是有人僞造cookie?如果我們的網站看到Facebook上登錄的用戶在cookie中有用戶ID 678678678,我們如何知道這個cookie不是僞造的?
回答
當您閱讀facebook的cookie時,它包含一個名爲'sig'的值。有了這個值,其他的cookie值和你的應用程序祕密,你可以散列cookie的內容並根據sig驗證它。如果它們匹配,那麼cookie是有效的。你可以相信這個結果,因爲只有你和Facebook可以訪問應用程序的祕密。這裏是Facebook的PHP SDK如何做的例子。任何可敬的Facebook SDK都會在內部完成這一切。
/**
* Validates a session_version=3 style session object.
*
* @param Array $session the session object
* @return Array the session object if it validates, null otherwise
*/
protected function validateSessionObject($session) {
// make sure some essential fields exist
if (is_array($session) &&
isset($session['uid']) &&
isset($session['access_token']) &&
isset($session['sig'])) {
// validate the signature
$session_without_sig = $session;
unset($session_without_sig['sig']);
$expected_sig = self::generateSignature(
$session_without_sig,
$this->getApiSecret()
);
if ($session['sig'] != $expected_sig) {
self::errorLog('Got invalid session signature in cookie.');
$session = null;
}
// check expiry time
} else {
$session = null;
}
return $session;
}
這裏是C#一樣的東西(Facebook C# SDK):
/// <summary>
/// Validates a session_version=3 style session object.
/// </summary>
/// <param name="session">The session to validate.</param>
protected override void ValidateSessionObject(FacebookSession session)
{
if (session == null)
{
return;
}
var signature = this.GenerateSignature(session);
if (session.Signature == signature.ToString())
{
return;
}
session = null;
}
/// <summary>
/// Generates a MD5 signature for the facebook session.
/// </summary>
/// <param name="session">The session to generate a signature.</param>
/// <returns>An MD5 signature.</returns>
/// <exception cref="System.ArgumentNullException">If the session is null.</exception>
/// <exception cref="System.InvalidOperationException">If there is a problem generating the hash.</exception>
protected override string GenerateSignature(FacebookSession session)
{
var args = session.Dictionary;
StringBuilder payload = new StringBuilder();
var parts = (from a in args
orderby a.Key
where a.Key != "sig"
select string.Format(CultureInfo.InvariantCulture, "{0}={1}", a.Key, a.Value)).ToList();
parts.ForEach((s) => { payload.Append(s); });
payload.Append(this.ApiSecret);
byte[] hash = null;
using (var md5 = System.Security.Cryptography.MD5CryptoServiceProvider.Create())
{
if (md5 != null)
{
hash = md5.ComputeHash(Encoding.UTF8.GetBytes(payload.ToString()));
}
}
if (hash == null)
{
throw new InvalidOperationException("Hash is not valid.");
}
StringBuilder signature = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
signature.Append(hash[i].ToString("x2", CultureInfo.InvariantCulture));
}
return signature.ToString();
}
不要將它存儲在cookie中。把它放在會話變量中,這樣你就可以控制
我認爲當用戶向我們的Web服務器發出請求時,沒有任何狀態 - 所有這一切都證實用戶確實在舊REST API和圖形API中的Cookie – 2010-10-23 05:51:43
不要把用戶ID放在cookie中。會話cookie應該只是一個隨機數字,映射到服務器端會話數據庫中的記錄。與該會話關聯的任何數據僅存儲在服務器端。
這樣,爲了僞造會話,攻擊者必須猜測當時實際使用的隨機數。鑑於有很多隨機數字和會話過期,這幾乎是不可能的。
中,在單擊「用Facebook登錄「,用戶ID總是在Facebook爲我們的網站設置的Cookie中(或者是Cookie的一部分)使用... – 2010-10-23 06:08:41
你說過你想顯示自己的數據庫的數據。根據任何Facebook cookies不要這樣做。只信任你自己的cookies。 – Thilo 2010-10-23 06:12:25
你可以信任的唯一事情是session_key
老REST API和access_token
的圖形API。一旦你得到它,將它傳遞給服務器端與您的數據重新調整請求。在服務器端調用facebook api並獲取當前用戶標識。一旦你得到了userid,你可以將它存儲在一個會話中,並在以後使用它。
這裏有幾種方法。低效:每當你執行一個認證的操作時,抓住FB cookie並使用其中的數據來做一個虛擬的API調用,看看訪問令牌是否有效,並匹配用戶(即抓/我?fields = id )。
效率更高:當您第一次看到用戶的FB cookie時,將該cookie存儲在用戶的服務器端會話中(在Cookie中傳遞給客戶端的會話ID足夠難猜測) )。
另一種方法,並不需要服務器端會話狀態:第一次看到用戶的FB cookie時,HMAC只使用您的服務器使用祕密的cookie,並將結果散列存儲在cookie中。然後你可以檢查FB cookie是否有一個有效的散列,如果有的話,你相信它。否則,你會回到驗證。
- 1. 如何將我的網站用戶「綁定」到他們的「Facebook」登錄ID?
- 2. 如何知道用戶使用他們的Facebook賬戶登錄,在我的網站首次
- 3. 如何讓用戶使用他們的Facebook帳戶登錄我的網站?
- 4. 如何顯示當前登錄到我們網站的用戶的用戶名?
- 5. 登錄Facebook的用戶名,如果我們使用Javascript
- 6. 如何讓用戶使用他們的aol賬戶登錄我的網站?
- 7. 如何找到登錄我們的網站或瀏覽我們的網站的客戶的IP地址
- 8. 如何重定向用戶,如果他們有一個cookie javascript
- 9. 如何獲得喜歡我的網站(不是Facebook網站)的Facebook用戶ID
- 10. 某些用戶的登錄問題,直到他們清除cookie
- 11. 如何用戶使用他們的Facebook用戶名和密碼登錄我的網站?
- 12. 它是用戶可以登錄我的網站上使用他們的Facebook帳戶
- 13. 有沒有人知道用戶是否仍在我的網站 - 而不是使用cookie或會話
- 14. 如何用戶在我的網站的twitter帳戶登錄
- 15. 嘗試使用java.net登錄到網站,但不知道如何處理cookie
- 16. 我在Facebook上的朋友看不到我在我的網站上做的「喜歡」。我看不到他們的。
- 17. 使用PHP或JavaScript Facebook SDK,我如何讓用戶登錄到我的網站?
- 18. 當在我們的網站上觀看YouTube視頻時,阻止用戶從我們的網站中被帶走
- 19. 我想看看用戶是否已登錄,如果不推送他們到登錄頁面
- 20. 我的vBulletin用戶如何知道他們有付費訂閱
- 21. 我如何登錄我的網站無縫使用Facebook的憑據,當我已經登錄我的Facebook帳戶?
- 22. 我不知道如何在facebook上註冊我的網站
- 23. 得到Facebook的用戶id,一旦他們喜歡他們的網頁/網站
- 24. 如何在我的網站上使用Facebook進行用戶登錄?
- 25. 在Django中,我如何知道當前登錄的用戶?
- 26. 如何知道Facebook用戶是否喜歡我們的「粉絲頁面」?
- 27. 如何將用戶ID保存在登錄cookie中?
- 28. 如何Facebook登錄我們系統中的相關用戶記錄
- 29. Authlogic:如何知道用戶上次訪問我的網站
- 30. 如何在用戶瀏覽器中啓用Cookie時,他們使用我的網站
要在這裏downvoted每一個答案的人:爲什麼呢? – Yuliy 2010-10-24 16:37:38
請參閱下面的答案。其他人都錯了。 :/ – 2010-10-24 16:43:44