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

时间:2010-08-08 05:54:10

标签: c# facebook .net-2.0 oauth

我能够使用示例here成功验证已签名的Facebook画布应用程序请求,但我无法解码有效负载。 Facebook文档指出signed_request中的第二个参数是base64url编码的JSON对象。在PHP中,使用json_decode解码有效负载:

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

C#中的等价物是什么?

6 个答案:

答案 0 :(得分:24)

以下内容可以帮助您..

注意:JObject引用来自JSON.NET,可通过http://james.newtonking.com/projects/json-net.aspxhttp://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中使用的内容..希望有所帮助

答案 1 :(得分:10)

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

答案 2 :(得分:9)

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

json参考也可以从nuGet

获得
Install-Package Newtonsoft.Json

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

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

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

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

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

答案 3 :(得分:2)

查看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处理所有这些。

答案 4 :(得分:2)

我已经改变了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; 
    }

答案 5 :(得分:2)

以下是使用Facebook SDK

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