Как декодировать OAuth 2.0 для Canvas Sign_request в C #? - PullRequest
17 голосов
/ 08 августа 2010

Я могу успешно проверить подписанный запрос для приложения на холсте Facebook, используя пример здесь , но я не могу декодировать полезную нагрузку. В документации Facebook говорится, что 2-й параметр в sign_request является объектом JSON в кодировке base64url. В PHP полезная нагрузка декодируется с использованием json_decode:

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

Что такое эквивалент в C #?

Ответы [ 6 ]

24 голосов
/ 19 августа 2010

Следующее должно помочь вам ..

( Примечание : ссылка на объект JObject из JSON.NET доступна через http://james.newtonking.com/projects/json-net.aspx и http://json.codeplex.com/)

Используемые пространства имен:

using System;
using System.Collections.Generic;
using System.Text;
using Newtonsoft.Json.Linq; // JSON.NET project 

Код:

public Dictionary<string,string> DecodePayload(string payload)
    {
        var encoding = new UTF8Encoding();
        var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/');
        var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '='));
        var json = encoding.GetString(base64JsonArray);
        var jObject = JObject.Parse(json);

        var parameters = new Dictionary<string, string>();
        parameters.Add("user_id", (string)jObject["user_id"] ?? "");
        parameters.Add("oauth_token", (string)jObject["oauth_token"] ?? "");
        var expires = ((long?) jObject["expires"] ?? 0);
        parameters.Add("expires", expires > 0 ? expires.ToString() : "") ;
        parameters.Add("profile_id", (string)jObject["profile_id"] ?? "");

        return parameters;
    }

Это то, что я использую в FaceSharp .. надеюсь, это поможет

10 голосов
/ 06 декабря 2011

Тот же код, но без зависимости Json.NET:

public IDictionary<string, object> DecodePayload(string payload)
{
    string base64 = payload.PadRight(payload.Length + (4 - payload.Length % 4) % 4, '=')
        .Replace('-', '+').Replace('_', '/');
    string json = Encoding.UTF8.GetString(Convert.FromBase64String(base64));
    return (IDictionary<string, object>)new JavaScriptSerializer().DeserializeObject(json);
}

Вы можете использовать это так:

public ActionResult Index()
{
    var dict = DecodePayload(Request["signed_request"].Split('.')[1]);
    return Content("Access Token: " + (string)dict["oauth_token"]);
}
9 голосов
/ 29 июля 2011

Извините, что-то вроде нуба StackOverflow, но для любого, кто пытается использовать метод JohnK для декодирования, он работает блестяще, всего пара советов по реализации для любого, как я и другие, с проблемой кодировки base64 ...

Ссылка Json также доступна из nuGet

Install-Package Newtonsoft.Json

http://developers.facebook.com/docs/guides/canvas/#auth объясняет элемент ["signature_request"] более подробно, но проще говоря, когда Facebook отправляет сообщения обратно (в моемслучай после запроса регистрации пользователя), вы можете получить данные из поста, но строка в двух частях, разделенных символом «.»- Таким образом, попытка декодировать ["signature_request"] завершится с ошибкой '.'не является символом Base64Первая часть - это подпись, позволяющая вам подтвердить, что сообщение пришло с Facebook (только мы и они знают, что сигнал декодируется), а вторая - полезная нагрузка.

Итак, я получил это для работы сследующий код (в контроллере MVC), источник - кнопка регистрации Facebook ...

<fb:registration fields="name,email"  redirect-uri="http://dev.devurlgoeshere.co.uk/Account/Register" width="530">
</fb:registration>

, а затем код контроллера отвечает на запрос регистрации

   [HttpPost]
    public ActionResult Register(object postData )
    {
        string requestData = Request.Form["signed_request"];
        string[] splitPayload = requestData.Split('.');
        string sig = splitPayload[0];
        string payload = splitPayload[1];
        var decodedObj = DecodePayload(payload);
        // get the items from the decodedObject
        string userFacebookID = decodedObj["user_id"];
        // now do what you want with their FacebookID
        return View();
    }

надеюсь, это поможеткто-то, и извините, если это должно было быть отредактировано / обратная связь или что-то еще ...

2 голосов
/ 29 ноября 2011

Вот как это сделать, используя Facebook SDK

var parsedSignedRequest = FacebookSignedRequest.Parse(FacebookApplication.Current, signed_request);
2 голосов
/ 13 мая 2011

Я изменил DecodePayload этим, и он прекрасно работает для меня:

    public Dictionary<string, string> DecodePayload(string payload) 
    {
        //Remove the bad part of signed_request
        //Begin
        string[] sB64String = payload.Split('.');
        payload = payload.Replace((sB64String[0] + "."), string.Empty);
        //End
        var encoding = new UTF8Encoding(); 
        var decodedJson = payload.Replace("=", string.Empty).Replace('-', '+').Replace('_', '/'); 
        var base64JsonArray = Convert.FromBase64String(decodedJson.PadRight(decodedJson.Length + (4 - decodedJson.Length % 4) % 4, '=')); 
        var json = encoding.GetString(base64JsonArray); 
        var jObject = JObject.Parse(json); 
        var parameters = new Dictionary<string, string>(); 
        parameters.Add("user_id", (string)jObject["user_id"] ?? ""); 
        parameters.Add("oauth_token", (string)jObject["oauth_token"] ?? ""); 
        var expires = ((long?)jObject["expires"] ?? 0); 
        parameters.Add("expires", expires > 0 ? expires.ToString() : ""); 
        parameters.Add("profile_id", (string)jObject["profile_id"] ?? ""); 
        return parameters; 
    }
2 голосов
/ 20 сентября 2010

Проверьте Facebook .Net SDK на Codeplex http://facebooksdk.codeplex.com. Он справится со всей «грязной работой» за вас. Например, я мог бы вызвать следующий код из действия контроллера или из Page_Load.

FacebookApp app = new FacebookApp();
string accessToken = app.Session.AccessToken;
long userId = app.UserId;

Вот и все. Вам не нужно беспокоиться о том, как Facebook возвращает вам данные или декодирует их. SDK обрабатывает все это для вас.

...