2011-01-01 3 views
5

Мой вопрос очень похож this, но я думаю, мне нужно сделать это еще на один шаг.Читать OAuth2.0 Signed_Request Регистрация на Facebook C# MVC

Facebook говорит: «Данные передаются вашему приложению в качестве подписанного запроса. Параметр signed_request - это простой способ убедиться, что данные, которые вы получаете, являются фактическими данными, отправленными Facebook».

После того, как пользователь зашел на мой сайт с asp C# MVC и нажал «Зарегистрироваться», URL-адрес перенаправления http://site/account/register. В этот момент (сообщение в элементе управления учетной записью/регистром) я хотел бы получить информацию пользователя, используя подписанный запрос, чтобы я мог зарегистрировать их на моем сайте локально. Я не могу понять, как получить доступ к данным, доступным в facebook.

$data = json_decode(base64_url_decode($payload), true); 

Что такое эквивалент в C#? Какой тип переменной/данных передается facebook в сообщении? И как мне получить доступ к «$ полезной нагрузке»?

[HttpPost] 
    public ActionResult RegisterFacebook(RegisterFacebookModel model) 
    { 
     Facebook.FacebookSignedRequest sr = Facebook.FacebookSignedRequest.Parse("secret", model.signed_request); 

     return View(model); 
    } 

ответ

8

Вот код, который мы использовали в Facebook C# SDK. Вам не нужно делать это вручную, если вы используете наш SDK, но если вам нужно сделать это самостоятельно здесь:

/// <summary> 
/// Parses the signed request string. 
/// </summary> 
/// <param name="signedRequestValue">The encoded signed request value.</param> 
/// <returns>The valid signed request.</returns> 
internal protected FacebookSignedRequest ParseSignedRequest(string signedRequestValue) 
{ 
    Contract.Requires(!String.IsNullOrEmpty(signedRequestValue)); 
    Contract.Requires(signedRequestValue.Contains("."), Properties.Resources.InvalidSignedRequest); 

    string[] parts = signedRequestValue.Split('.'); 
    var encodedValue = parts[0]; 
    if (String.IsNullOrEmpty(encodedValue)) 
    { 
     throw new InvalidOperationException(Properties.Resources.InvalidSignedRequest); 
    } 

    var sig = Base64UrlDecode(encodedValue); 
    var payload = parts[1]; 

    using (var cryto = new System.Security.Cryptography.HMACSHA256(Encoding.UTF8.GetBytes(this.AppSecret))) 
    { 
     var hash = Convert.ToBase64String(cryto.ComputeHash(Encoding.UTF8.GetBytes(payload))); 
     var hashDecoded = Base64UrlDecode(hash); 
     if (hashDecoded != sig) 
     { 
      return null; 
     } 
    } 

    var payloadJson = Encoding.UTF8.GetString(Convert.FromBase64String(Base64UrlDecode(payload))); 
    var data = (IDictionary<string, object>)JsonSerializer.DeserializeObject(payloadJson); 
    var signedRequest = new FacebookSignedRequest(); 
    foreach (var keyValue in data) 
    { 
     signedRequest.Dictionary.Add(keyValue.Key, keyValue.Value.ToString()); 
    } 

    return signedRequest; 
} 

/// <summary> 
/// Converts the base 64 url encoded string to standard base 64 encoding. 
/// </summary> 
/// <param name="encodedValue">The encoded value.</param> 
/// <returns>The base 64 string.</returns> 
private static string Base64UrlDecode(string encodedValue) 
{ 
    Contract.Requires(!String.IsNullOrEmpty(encodedValue)); 

    encodedValue = encodedValue.Replace('+', '-').Replace('/', '_').Trim(); 
    int pad = encodedValue.Length % 4; 
    if (pad > 0) 
    { 
     pad = 4 - pad; 
    } 

    encodedValue = encodedValue.PadRight(encodedValue.Length + pad, '='); 
    return encodedValue; 
} 

Вы можете найти полный исходный код здесь: http://facebooksdk.codeplex.com/SourceControl/changeset/view/f8109846cba5#Source%2fFacebook%2fFacebookApp.cs

+0

Спасибо за ваш ответ, Натан. У меня было мало времени, и у меня еще не было возможности повторить тест, но то, что вы показали, имеет смысл. Я также посмотрю на SDK. – Josh

+0

Думаю, я до сих пор не понимаю, как реализовать это (или SDK). Является ли signed_request отправленным как сообщение в redirect-uri в fb: регистрационном коде? Я использую js SDK для входа/регистрации, но затем пытаюсь использовать FacebookAPI, на который вы ссылались для более глубокой интеграции, когда обрабатывается членский материал. Я думаю, если бы я мог пройти мимо этого момента, я был бы хорош ... Я просто повесил трубку. Я создаю проект MVC и пытаюсь указать обратный вызов регистрации на обработчик http-почты, но затем нужно декодировать объект json, который должен отправить fb. Но я ничего не получил. – Josh

+0

Nathan - могу я попросить быстрое наблюдение сейчас, когда я использую SDK - я вижу все параметры из signed_request, кроме параметров «Регистрация». (т. е. «регистрация»: { «имя»: «Пол Тарьян» ... я что-то не так? Когда я отправляю на тестовую страницу в facebook, я вижу их, но они недоступны после прохождения декодирования SDK . "электронная почта": "[email protected]", "место": { "имя": "Сан-Франциско, Калифорния", "идентификатор": 114952118516947 }, – Josh

1

основе ваш комментарий, похоже, вы все еще ищете ответ, который отправляет FB. Я считаю, что он содержится в коллекции форм в объекте запроса HttpContext. Так со страницы вы указываете в качестве редиректа, вы должны быть в состоянии вытащить его из:

HttpContext.Current.Request.Form («signed_request»)

Надежда, что помогает пролить некоторый свет. Я все еще участвую в этом, так как это не может быть лучшим решением.

спасибо, Jason

+0

Спасибо, Джейсон. Я работаю над проектом MVC, поэтому HttpContext недоступен в среде контроллера, но я понял, как объединить два ответа и заставить их в основном работать! Использование Facebook-SDK упростило обработку возвращенного «signed_request». – Josh

1

Вот как сделать это с помощью Facebook SDK

var parsedSignedRequest = FacebookSignedRequest.Parse(FacebookApplication.Current, signed_request); 
+4

Это устарело, если вы используете Facebook SDK v6. Теперь это 'var fb = new FacebookClient(); dynamic signedRequest = fb.ParseSignedRequest ("app_secret", Request.Params ["signed_request"]); ' –

Смежные вопросы