2010-08-08 21 views
17

Jestem w stanie pomyślnie zweryfikować podpisane żądanie dla aplikacji canvas na Facebooku, używając przykładu here, ale nie mogę odszyfrować ładunku. Dokumentacja Facebooka stwierdza, że ​​drugim parametrem w signed_request jest obiekt JSON zakodowany w base64url. W PHP ładunek jest dekodowany z wykorzystaniem json_decode:Jak odkodować OAuth 2.0 dla Canvas signed_request w języku C#?

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

Jaki jest odpowiednik w C#?

+0

Znalazłeś na zewnątrz? – cdpnet

+0

Czy próbowałeś użyć Facebook C# SDK: http://github.com/facebook/csharp-sdk? – Romhein

+1

C# SDK na Facebooku na github nie obsługuje niczego z uwierzytelnianiem, wykonuje tylko żądania API. –

Odpowiedz

24

Poniższy powinno pomóc ..

(Uwaga: Odniesienie JObject wynosi od Json.NET dostępnej poprzez http://james.newtonking.com/projects/json-net.aspx i http://json.codeplex.com/)

Przestrzenie nazw używanych:

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

Kodeksu :

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; 
    } 

To jest to, czego używam w FaceSharp .. mam nadzieję, że pomaga

+0

Dzięki, to działało świetnie! –

+1

+1 Bardzo pomocny. Zaktualizowałem odpowiedź o obszary nazw i odwołanie do używanej biblioteki JSON (w przypadku, gdy oprogramowanie FaceSharp nie jest zainstalowane - prawdopodobnie zapewnia bibliotekę JSON.NET jako część samej siebie.) –

+0

Ale to nie działa dla mnie, ponieważ kod nie powiódł się . – Moons

2

Sprawdź pakiet SDK Facebook .Net na Codeplex http://facebooksdk.codeplex.com. Zrobi dla ciebie całą "brudną robotę". Na przykład mógłbym wywołać poniższy kod z akcji kontrolera lub z Page_Load.

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

To wszystko. Nie musisz się martwić, w jaki sposób Facebook zwraca Ci dane lub je odkodowuje. SDK obsługuje to wszystko dla ciebie.

+0

Aplikacja FacebookApp = new FacebookApp(); jest teraz aplikacja FacebookApp = new FacebookApp(); I tak nie widzę, aby uzyskać userId bez wywoływania app.Get ("ja") .. – AyKarsi

+0

Nie wyjaśnił, jak SDK dekoduje podpisane_request :(Ustawiam akcję Deauthorize(), aby obsłużyć signed_request, który jest POST przez Facebook do mojej akcji z parametrem "signed_request" jako ciągiem.Aby go zdekodować, aby uzyskać identyfikator użytkownika – Korayem

2

mam zmienić DecodePayload przez to i to działa dobrze dla mnie:

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

Dlaczego nie zrobić payload = sB64String [1], zamiast payload = payload.Replace ((sB64String [0 ] + "."), string.Empty); –

9

Niestety, trochę noob StackOverflow, ale dla każdego, kto próbuje użyć metody JohnK do dekodowania, to działa świetnie, tylko kilka wskazówek wdrożeniowych dla kogoś takiego jak ja i inni z kwestii kodowania base64 ....

odniesienie JSON jest również dostępny z Nuget

Install-Package Newtonsoft.Json 

http://developers.facebook.com/docs/guides/canvas/#auth wyjaśnia bardziej szczegółowo element ["signed_request"], ale mówiąc krótko, gdy Facebook odsyła z powrotem (w moim przypadku po żądaniu rejestracji użytkownika), możesz pobrać dane z tego wpisu, ale ciąg jest w DWÓCH CZĘŚCIach, oddzielonych przez "." - Jako takie, próba dekodowania ["signed_request"] zakończy się niepowodzeniem jako "." nie jest znakiem Base64. Pierwsza część to podpis umożliwiający sprawdzenie, czy post pochodzi z Facebooka (tylko my i oni znamy sig do odkodowania), a drugi to ładunek.

Tak, mam to do pracy z następującego kodu (w kontroler MVC), źródło jest przycisk Rejestracja Facebook ....

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

a następnie kod Kontroler odpowiada na żądania rejestracji

[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(); 
    } 

Mam nadzieję, że to pomoże komuś i przepraszam, czy to powinna być edycja/opinia lub cokolwiek ...

2

Oto jak to zrobić za pomocą Facebook SDK

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

samego kodu, ale bez uzależnienia 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); 
} 

Można go używać tak:

public ActionResult Index() 
{ 
    var dict = DecodePayload(Request["signed_request"].Split('.')[1]); 
    return Content("Access Token: " + (string)dict["oauth_token"]); 
} 
+0

dict ["oauth_token"] - nie jest już kluczem: jest "kod" jeden, czy to powinienem użyć? –

+0

Pierwsza funkcja zadziałała dla mnie znakomicie – Moons

Powiązane problemy