如何在 C# 中解码 Canvassigned_request 的 OAuth 2.0?

发布于 2024-09-13 00:56:19 字数 381 浏览 4 评论 0 原文

我能够使用示例 这里,但我无法解码有效负载。 Facebook 文档指出,signed_request 中的第二个参数是一个 base64url 编码的 JSON 对象。在 PHP 中,有效负载使用 json_decode 进行解码:

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

C# 中的等效项是什么?

I'm able to successfully validate the signed request for a Facebook canvas app using the example here, but I'm unable to decode the payload. The Facebook documentation states that the 2nd parameter in signed_request is a base64url encoded JSON object. In PHP the payload is decoded using json_decode:

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

What is the equivalent in C#?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

提笔落墨 2024-09-20 00:56:19

以下内容应该可以帮助您..

注意: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 中使用的..希望它有帮助

The following should help you out..

(Note: The JObject reference is from JSON.NET available via http://james.newtonking.com/projects/json-net.aspx and http://json.codeplex.com/)

Namespaces used:

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

It is what I'm using in FaceSharp.. hope it helps

爱本泡沫多脆弱 2024-09-20 00:56:19

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

Same code but without Json.NET dependency:

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

You can use it like this:

public ActionResult Index()
{
    var dict = DecodePayload(Request["signed_request"].Split('.')[1]);
    return Content("Access Token: " + (string)dict["oauth_token"]);
}
找个人就嫁了吧 2024-09-20 00:56:19

抱歉,有点像 StackOverflow 菜鸟,但对于任何尝试使用 JohnK 的方法进行解码的人来说,它都非常有效,对于像我这样的人和其他有 Base64 编码问题的人来说,只需一些实现技巧......

Json 参考也是可从 nuGet

Install-Package Newtonsoft.Json

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

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

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

然后控制器代码响应注册请求

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

希望这对某人有帮助,如果这应该是的话,我很抱歉编辑/反馈或其他...

Sorry, bit of a StackOverflow noob, but for anyone trying to use JohnK's method to decode, it works brilliantly, just a couple of implementation tips for anyone like me and the others with the base64 encoding issue....

The Json reference is also available from nuGet

Install-Package Newtonsoft.Json

http://developers.facebook.com/docs/guides/canvas/#auth explains the ["signed_request"] element in more detail, but put simply, when Facebook posts back (in my case after a user registration request), you can get the data from the post, but the string is in TWO PARTS, separated by a '.' - As such, trying to decode ["signed_request"] will fail as '.' isn't a Base64 char. The first part is the signature to allow you to validate that the post came from Facebook (only us and them know the sig to decode) and the second is the payload.

So, I got this to work with the following code (in a MVC controller), source is a Facebook registration button....

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

and then the Controller code responds to the registration request

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

hope this helps someone, and sorry if this should have been edit/feedback or whatever...

乖乖兔^ω^ 2024-09-20 00:56:19

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

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

就是这样。您实际上不需要担心 facebook 如何将数据返回给您或对其进行解码。 SDK 会为您处理所有这些事情。

Check out the Facebook .Net SDK on Codeplex http://facebooksdk.codeplex.com. It will handle all the 'dirty work' for you. For example, I could call the following code either from a controller action or on Page_Load.

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

Thats it. You don't really need to worry about how facebook is returning the data to you or decoding it. The SDK handles all that for you.

从来不烧饼 2024-09-20 00:56:19

我已经通过这个更改了 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; 
    }

i have change the DecodePayload by this and it work fine for me:

    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; 
    }
生生漫 2024-09-20 00:56:19

以下是如何使用 Facebook SDK 执行此操作

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

Here's how to do it using Facebook SDK

var parsedSignedRequest = FacebookSignedRequest.Parse(FacebookApplication.Current, signed_request);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文