2010-07-27 73 views
1

我試圖將此PHP cookie解析片段轉換爲C#,但我的PHP有點生疏。它取自facebook SDK sample什麼是這個PHP cookie解析片段的C#等價物?

<?php 

define('FACEBOOK_APP_ID', 'your application id'); 
define('FACEBOOK_SECRET', 'your application secret'); 

function get_facebook_cookie($app_id, $application_secret) { 
    $args = array(); 
    parse_str(trim($_COOKIE['fbs_' . $app_id], '\\"'), $args); 
    ksort($args); 
    $payload = ''; 
    foreach ($args as $key => $value) { 
     if ($key != 'sig') { 
      $payload .= $key . '=' . $value; 
     } 
    } 
    if (md5($payload . $application_secret) != $args['sig']) { 
     return null; 
    } 
    return $args; 
} 

$cookie = get_facebook_cookie(FACEBOOK_APP_ID, FACEBOOK_SECRET); 
echo 'The ID of the current user is ' . $cookie['uid']; 

?> 

這是我到目前爲止,但它並不完全正確:

protected override void OnInit(EventArgs e) 
{ 
    base.OnInit(e); 

    HttpCookie cookie = GetCookie(); 
    IsLoggedIn = cookie != null; 
} 

private HttpCookie GetCookie() 
{ 
    // based on the php example at http://developers.facebook.com/docs/authentication/ 
    HttpCookie cookie = Request.Cookies["fbs_" + FacebookClientId]; 
    StringBuilder payload = new StringBuilder(); 
    if (cookie != null) 
    { 
     foreach (string key in cookie.Values.Keys) 
     { 
      if (key != "sig") 
      { 
       payload.Append(key + "=" + cookie.Values[key]); 
      } 
     } 

     string sig = cookie.Values["sig"]; 

     if (sig == GetMD5Hash(payload.ToString())) 
     { 
      return cookie; 
     } 
    } 

    return null; 
} 

public string GetMD5Hash(string input) 
{ 
    MD5CryptoServiceProvider cryptoServiceProvider = new MD5CryptoServiceProvider(); 
    byte[] bytes = Encoding.UTF8.GetBytes(input); 
    bytes = cryptoServiceProvider.ComputeHash(bytes); 
    StringBuilder s = new StringBuilder(); 

    foreach (byte b in bytes) 
    { 
     s.Append(b.ToString("x2").ToLower()); 
    } 

    return s.ToString(); 
} 

的一個部分,我不知道是parse_str(trim($_COOKIE['fbs_' . $app_id], '\\"'), $args);。從我可以告訴它從修剪後的cookie值中創建一個數組。任何人都可以提供幫助嗎?

+1

這可能會幫助:http://php.net/manual/en/function.parse-str.php它解碼查詢字符串,並增加了鍵/值對組合。 – JAL 2010-07-27 02:56:55

+0

因此,它假設每個鍵/值對由'&'分隔?那很有意思。我會看到我可以做什麼。 – jrummell 2010-07-27 03:02:01

+0

好點 - 這對餅乾來說有點奇怪,不是嗎? – JAL 2010-07-27 03:34:14

回答

1

我原來的C#版本中有幾個問題。

  • 我忘了將FacebookSecret作爲鹽包含在MD5哈希中。
  • 正如George Marian和Alex JL所解釋的那樣,cookie.Value需要作爲查詢字符串進行修剪和分析。
  • 解析的cookie值需要爲UrlDecoded。我想ASP.NET UrlEncodes他們創建Cookie對象時。
  • 默認編碼應該用來創建散列,而不是UTF8。

這裏的工作解決方案:

private HttpCookie GetCookie() 
{ 
    // based on the php example at http://developers.facebook.com/docs/guides/canvas/#canvas 
    HttpCookie cookie = Request.Cookies["fbs_" + FacebookClientId]; 
    if (cookie != null) 
    { 
     var pairs = from pair in cookie.Value.Trim('"', '\\').Split('&') 
        let indexOfEquals = pair.IndexOf('=') 
        orderby pair 
        select new 
           { 
            Key = pair.Substring(0, indexOfEquals).Trim(), 
            Value = pair.Substring(indexOfEquals + 1).Trim() 
           }; 

     IDictionary<string, string> cookieValues = 
      pairs.ToDictionary(pair => pair.Key, pair => Server.UrlDecode(pair.Value)); 

     StringBuilder payload = new StringBuilder(); 
     foreach (KeyValuePair<string, string> pair in cookieValues) 
     { 
      Response.Write(pair.Key + ": " + pair.Value + "<br/>\n"); 

      if (pair.Key != "sig") 
      { 
       payload.Append(pair.Key + "=" + pair.Value); 
      } 
     } 

     string sig = cookieValues["sig"]; 
     string hash = GetMd5Hash(payload + FacebookSecret); 

     if (sig == hash) 
     { 
      return cookie; 
     } 
    } 

    return null; 
} 

private static string GetMd5Hash(string input) 
{ 
    MD5CryptoServiceProvider cryptoServiceProvider = new MD5CryptoServiceProvider(); 
    byte[] bytes = Encoding.Default.GetBytes(input); 
    byte[] hash = cryptoServiceProvider.ComputeHash(bytes); 

    StringBuilder s = new StringBuilder(); 
    foreach (byte b in hash) 
    { 
     s.Append(b.ToString("x2")); 
    } 

    return s.ToString(); 
} 
+0

我最近轉向了Facebook C#SDK,爲您處理這個混亂! http://facebooksdk.codeplex.com/ – jrummell 2010-11-27 22:11:15

2

如果我正確地讀它:

trim($_COOKIE['fbs_' . $app_id], '\\"') 

將削減\並從一開始就"和存儲在名爲fbs_FACEBOOK_APP_ID cookie的值的結束(雙反斜槓逃生的反斜槓一個單引號字符串,修剪可以告訴要從字符串中刪除哪些字符)

同時,parse_str然後將它解析爲一個查詢字符串,並將其解析爲關聯數組。所以,我假設這個cookie的值應該看起來像一個查詢字符串。

希望這會有所幫助。

+0

我會試試看,謝謝。 – jrummell 2010-07-27 12:34:57

+0

這有助於解決我的一個問題,謝謝! – jrummell 2010-07-28 03:21:29