代码之家  ›  专栏  ›  技术社区  ›  jrummell

这个php cookie解析代码段的C等价物是什么?

  •  1
  • jrummell  · 技术社区  · 16 年前

    我正试图将这个php cookie解析代码段转换成c,但我的php有点生疏。它是从一个 facebook SDK sample .

    <?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值创建了一个数组。有人能提供帮助吗?

    2 回复  |  直到 16 年前
        1
  •  2
  •   George Marian    16 年前

    如果我读得正确:

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

    将修剪 \ 和 " 从存储在名为cookie的cookie中的值的开始和结束 fbs_FACEBOOK_APP_ID (双反斜杠转义单引号字符串中的反斜杠。可以告诉trim从字符串中删除哪些字符。)

    与此同时, parse_str 然后将其解析为一个关联数组,就像它是一个查询字符串一样。所以,我假设这个cookie的值应该像一个查询字符串。

    希望这有帮助。

        2
  •  1
  •   jrummell    16 年前

    在我原来的C版本中有一些问题。

    • 我忘了把facebooksecret作为salt包含在MD5哈希中。
    • 正如GeorgeMarian和AlexJL解释的那样,cookie.value需要被修剪并解析为一个查询字符串。
    • 解析的cookie值需要进行urledcoded。我猜在创建cookie对象时,ASP.NET URLEN会对它们进行编码。
    • 默认编码应该用于创建哈希,而不是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();
    }