Come decodificare OAuth 2.0 per Canvas firm_request in C #?

Sono in grado di convalidare correttamente la richiesta firmata per un’app di canvas di Facebook utilizzando l’esempio qui , ma non sono in grado di decodificare il carico utile. La documentazione di Facebook afferma che il secondo parametro in firm_request è un object JSON con codifica base64url. In PHP il carico utile viene decodificato usando json_decode:

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

Qual è l’equivalente in C #?

Il seguente dovrebbe aiutarti

( Nota : il riferimento a JObject è disponibile da JSON.NET disponibile su http://james.newtonking.com/projects/json-net.aspx e http://json.codeplex.com/ )

Spazi dei nomi usati:

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

Codice:

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

È quello che sto usando in FaceSharp .. spero che aiuti

Stesso codice ma senza dipendenza Json.NET:

 public IDictionary 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)new JavaScriptSerializer().DeserializeObject(json); } 

Puoi usarlo in questo modo:

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

Scusa, un po ‘di noob di StackOverflow, ma per chiunque cerchi di usare il metodo di JohnK per decodificarlo, funziona brillantemente, solo un paio di suggerimenti per l’implementazione per chiunque come me e gli altri con il problema di codifica base64 ….

Il riferimento Json è disponibile anche da nuGet

 Install-Package Newtonsoft.Json 

http://developers.facebook.com/docs/guides/canvas/#auth spiega l’elemento [“signed_request”] in maggior dettaglio, ma in parole povere, quando Facebook postback (nel mio caso dopo una richiesta di registrazione dell’utente), tu può ottenere i dati dal post, ma la stringa è in DUE PARTI, separati da un ‘.’ – Come tale, provare a decodificare [“signed_request”] fallirà come ‘.’ non è un carattere Base64. La prima parte è la firma per consentire di convalidare che il post proviene da Facebook (solo noi e loro conoscono il sig per decodificare) e il secondo è il payload.

Quindi, ho ottenuto che questo funzioni con il seguente codice (in un controller MVC), la sorgente è un pulsante di registrazione di Facebook ….

   

e quindi il codice del controller risponde alla richiesta di registrazione

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

Spero che questo aiuti qualcuno e scusa se questo dovrebbe essere stato modificato / feedback o qualsiasi altra cosa …

Controlla l’SDK di Facebook .Net su Codeplex http://facebooksdk.codeplex.com . Gestirà tutto il “lavoro sporco” per te. Ad esempio, potrei chiamare il codice seguente sia da un’azione del controller che da Page_Load.

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

Questo è tutto. Non devi davvero preoccuparti di come Facebook ti restituisce i dati o decodificarli. L’SDK gestisce tutto ciò che per te.

Ho cambiato il DecodePayload da questo e funziona bene per me:

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

Ecco come farlo usando Facebook SDK

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