2010-08-08 9 views
17

Ich bin in der Lage, die signierte Anfrage für eine Facebook Canvas App mit dem Beispiel here erfolgreich zu validieren, aber ich kann die Nutzlast nicht dekodieren. Die Facebook-Dokumentation besagt, dass der zweite Parameter in signed_request ein base64url-codiertes JSON-Objekt ist. In PHP wird die Nutzlast mit json_decode dekodiert:Wie dekodiert man OAuth 2.0 für Canvas signed_request in C#?

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

Was ist das Äquivalent in C#?

+0

Haben Sie gefunden aus? – cdpnet

+0

Haben Sie versucht, das Facebook C# SDK zu verwenden: http://github.com/facebook/csharp-sdk? – Romhein

+1

Das Facebook C# SDK auf Github behandelt nichts mit Authentifizierung, es tut nur API-Anfragen. –

Antwort

24

Die folgenden sollten Sie helfen ..

(Hinweis: Die JObject Referenz von JSON.NET erhältlich über http://james.newtonking.com/projects/json-net.aspx und http://json.codeplex.com/)

Namespaces verwendet:

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

-Code :

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

Es ist was ich benutze in FaceSharp .. hoffe es hilft

+0

Danke, das hat super funktioniert! –

+1

+1 Sehr hilfreich. Ich aktualisierte die Antwort mit Namespaces und Verweis auf die verwendete JSON-Bibliothek (falls die FaceSharp-Software nicht installiert ist - bietet es wahrscheinlich die JSON.NET-Bibliothek als Teil von sich selbst.) –

+0

Aber das funktioniert nicht für mich, da der Code fehlgeschlagen ist . – Moons

2

Schauen Sie sich die Facebook. NET SDK auf Codeplex http://facebooksdk.codeplex.com. Es wird alle "schmutzige Arbeit" für Sie erledigen. Zum Beispiel könnte ich den folgenden Code entweder von einer Controller-Aktion oder von Page_Load aufrufen.

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

Das ist es. Sie müssen sich nicht wirklich darum sorgen, wie Facebook die Daten an Sie zurückgibt oder entschlüsselt. Das SDK übernimmt all das für Sie.

+0

FacebookApp-App = neue FacebookApp(); ist jetzt FacebookApp app = new FacebookApp(); Ich sehe sowieso nicht um die userId ohne app.get.Get ("me") .. – AyKarsi

+0

Sie haben nicht erläutert, wie das SDK decodiert die signed_request :(Ich bin eine Deauthorize() Aktion einrichten, um signed_request zu handhaben, die ist ein POST von Facebook zu meiner Aktion mit dem Parameter "signed_request" als String. Ich möchte es decodieren, um die user_id – Korayem

2

ich habe die DecodePayload durch diese ändern und es gut für mich arbeiten:

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

Warum nicht zu tun Nutzlast = sB64String [1]; anstelle von Payload = Payload.Replace ((sB64String [0 ] + "."), string.Empty); –

9

Sorry, bisschen ein Stackoverflow noob, aber für jeden, der versucht Jöhnk Methode zu verwenden, zu entschlüsseln, es funktioniert hervorragend, nur ein paar Tipps für die Umsetzung wie jemand mir und den anderen mit dem base64-Codierung Problem ....

die Json Referenz auch von NuGet

Install-Package Newtonsoft.Json 
verfügbar ist

http://developers.facebook.com/docs/guides/canvas/#auth erklärt das ["signed_request"] -Element detaillierter, aber einfach gesagt, wenn Facebook Posts zurück (in meinem Fall nach einer Benutzerregistrierungsanfrage), können Sie die Daten aus dem Post erhalten, aber die Zeichenfolge ist in ZWEI TEILE, getrennt durch eine '.' - Daher wird der Versuch, ["signed_request"] zu dekodieren, als "." ist kein Base64-Zeichen. Der erste Teil ist die Unterschrift, mit der Sie bestätigen können, dass der Beitrag von Facebook kam (nur wir und sie wissen, dass das Sigde zu entschlüsseln ist), und der zweite Teil ist die Nutzlast.

So habe ich dies mit dem folgenden Code zu arbeiten (in einem MVC-Controller), Quelle ist eine Facebook-Registrierungstaste ....

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

und dann der Controller-Code reagiert auf die Registrierungsanforderung

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

hoffe das hilft jemandem, und es tut mir leid, wenn dies hätte bearbeiten/Feedback oder was auch immer ...

2

Hier ist, wie es zu tun mit Facebook SDK

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

gleichen Code aber ohne Json.NET Abhängigkeit:

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

Sie können es wie folgt verwenden:

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

dict ["oauth_token"] - ist nicht mehr ein schlüssel: es gibt 'code' eins, soll ich das verwenden? –

+0

Die erste funktion hat bei mir super geklappt – Moons