如何在C#中为Canvas signed_request解码OAuth 2.0?

我可以使用此处的示例成功validation已签名的Facebookcanvas应用程序请求,但我无法解码有效负载。 Facebook文档声明signed_request中的第二个参数是base64url编码的JSON对象。 在PHP中,使用json_decode对有效负载进行解码:

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

C#中的等价物是什么?

以下内容应该可以帮到你..

注意 :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 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; } 

这是我在FaceSharp中使用的…希望它有所帮助

相同的代码,但没有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); } 

你可以像这样使用它:

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

对不起,有点StackOverflow noob,但是对于任何试图使用JohnK的方法进行解码的人来说,它的工作非常出色,只有像我这样的人和其他有base64编码问题的人提供了几个实现技巧….

json参考也可以从nuGet获得

 Install-Package Newtonsoft.Json 

http://developers.facebook.com/docs/guides/canvas/#auth更详细地解释了%5B“signed_request”%5D元素,但简单地说,当Facebook回发时(在我的情况下在用户注册请求之后),你可以从post中获取数据,但字符串是两个部分,用'。'分隔。 – 因此,尝试解码[“signed_request”]将失败为’。’ 不是Base64 char。 第一部分是签名,允许您validationpost来自Facebook(只有我们和他们知道要解码的信号),第二部分是有效负载。

所以,我得到这个使用以下代码(在MVC控制器中),源是一个Facebook注册按钮….

   

然后Controller代码响应注册请求

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

希望这对某人有所帮助,对不起,如果这应该是编辑/反馈或其他什么…

查看Codeplex http://facebooksdk.codeplex.com上的Facebook .Net SDK。 它将为您处理所有“肮脏的工作”。 例如,我可以从控制器操作或Page_Load调用以下代码。

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

而已。 你真的不需要担心facebook如何将数据返回给你或解码它。 SDK会为您处理所有这些。

我已经改变了DecodePayload,它对我来说很好用:

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

以下是使用Facebook SDK的方法

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