Что такое эквивалент C # этого фрагмента PHP-файла cookie? - PullRequest
1 голос
/ 27 июля 2010

Я пытаюсь преобразовать этот фрагмент кода PHP cookie в C #, но мой PHP немного ржавый. Он взят из образца Facebook SDK .

<?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 ]

2 голосов
/ 27 июля 2010

Если я правильно читаю:

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

Обрезает \ и " от начала и конца значения, хранящегося в файле cookie с именем fbs_FACEBOOK_APP_ID (Двойная обратная косая черта экранирует обратную косую черту в одной строке в кавычках. И обрезать можно сказать какие символы обрезать из строки.)

Тем временем parse_str затем анализирует это, как если бы это была строка запроса, в ассоциативный массив. Итак, я предполагаю, что значение этого файла cookie должно выглядеть как строка запроса.

Надеюсь, это поможет.

1 голос
/ 28 июля 2010

В исходной версии C # было несколько проблем.

  • Я забыл включить FacebookSecret как соль в хеш MD5.
  • Файл cookie. Значение должно быть обрезано и проанализировано как строка запроса, как объяснили Джордж Мариан и Алекс Дж.
  • Анализируемые значения файлов 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();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...