迁移到OAuth 2.0后获取access_token的问题

时间:2011-08-26 07:46:02

标签: c# facebook oauth-2.0

我已尝试将我的应用迁移到OAuth 2.0例程。我无法从JavaScript API设置的cookie中获取access_token。我解码了cookie中的信息,但是我获得了代码而不是access_token和用户信息。这似乎是一个相当奇怪的变化。 是否有任何解决方法,因为当您在获取代码时未指定redirect_uri时,似乎无法将代码交换到access_token。

我已经考虑过从JavaScript API中的响应中获取access_token并将其存储在cookie中,但是这有点违背了扩展安全性的全部目的,我想问一下是否有正确的方法来实现它。

可能是我做错了,如果是这样的话请告诉我:)

修改 我知道cookie包含一个签名请求,但根据文档,签名请求应该包含我需要的信息,如access_token和uid,但在我的实例中它只保存代码。这基本上是我不理解的部分。

4 个答案:

答案 0 :(得分:10)

事实证明(即使没有记录)我们需要自己交换access_token的代码。我认为这是一个完全浪费,因为这是关于旧cookie的好处。获取access_token非常快捷方便。

反正。要从新cookie获取access_token,您需要执行以下操作:

public string ReturnAccessToken()
{
    HttpCookie cookie = htc.Request.Cookies[string.Format("fbsr_{0}", facebookAppID)];
    string jsoncode = System.Text.ASCIIEncoding.ASCII.GetString(FromBase64ForUrlString(cookie.Value.Split(new char[] { '.' })[1]));

    JsonData data = JsonMapper.ToObject(jsoncode);

    getAccessToken(data["code"].ToJson()
}

private string getAccessToken(string code)
{
    //Notice the empty redirect_uri! And the replace on the code we get from the cookie.
    string url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&client_secret={2}&code={3}", "YOUR_APP_ID", "", "YOUR_APP_SECRET", code.Replace("\"", ""));

    System.Net.HttpWebRequest request = System.Net.WebRequest.Create(url) as System.Net.HttpWebRequest;
    System.Net.HttpWebResponse response = null;

    using (response = request.GetResponse() as System.Net.HttpWebResponse)
    {
        System.IO.StreamReader reader = new System.IO.StreamReader(response.GetResponseStream());

        string retVal = reader.ReadToEnd();
        return retVal;
    }
}

public byte[] FromBase64ForUrlString(string base64ForUrlInput)
{
    int padChars = (base64ForUrlInput.Length % 4) == 0 ? 0 : (4 - (base64ForUrlInput.Length % 4));
    StringBuilder result = new StringBuilder(base64ForUrlInput, base64ForUrlInput.Length + padChars);
    result.Append(String.Empty.PadRight(padChars, '='));
    result.Replace('-', '+');
    result.Replace('_', '/');
    return Convert.FromBase64String(result.ToString());
}

这可能看起来有点多余,但我想您可以将access_token存储在会话变量中。如果您这样做并在Facebook上框架您的应用程序,您需要知道如果用户将其浏览器隐私设置设置为中等,它将无法在IE 6,7和8中运行。有一个解决方法,但由于它不是这个问题的一部分,我不会写它。如果人们真的想要它,写一个评论,我会告诉它:)

-----------------------------------的修改 ---- --------------------------------------

使用任何旧的IE浏览器时,您无法在Iframed 的网页中使用Cookie或会话变量,例如Facebook上的网页。这是一个在编码中无法真正解决的问题。足够我的意思是解决方案并不好。您需要在响应中设置p3p-header。您当然可以在编写所有服务页面时执行此操作,但最简单的解决方案(如果您使用.NET服务器来托管页面)是为IIS设置p3p策略。可以在http://support.microsoft.com/kb/324013中看到相关指南。你在p3p政策中所写的内容应该无关紧要(如果你检查Facebook拥有你可以看到他们使用“我们没有p3p政策”),重要的是有一些东西。我有使用麻烦虽然随机文本,但如果您使用示例中的文本应该没有问题:)

这让我永远找到了,所以我希望有人可以使用它:D

答案 1 :(得分:3)

不幸的是我没有直接得到答案,但我确实有一个文档错误,我提交给Facebook,以试图获取文档:http://bugs.developers.facebook.net/show_bug.cgi?id=20363

我遇到类似的问题,当我尝试从FB.login的authResponse解码signedRequest时,它们的有效负载包含如下内容:

{"algorithm":"HMAC-SHA256","code":"THE_CODE_HERE","issued_at":1315433244,"user_id":"THE_USER_ID"}

如您所述,文档确实讨论了如何将该代码转换为access_token。这似乎出现在“服务器端”文档中:http://developers.facebook.com/docs/authentication/

如果从FB.login获取accessToken,你可以从js中获取它并缓存它,但正如你所说,实际上并没有签名,并且可能相对容易被伪造。

你是对的,这似乎没有任何有用的信息在这里描述:developers.facebook.com/docs/authentication/signed_request/(http已删除,因为我还没有足够的声誉点发布超过2个链接 - 抱歉)

也许你可以投票我的错误?我也会在这个bug上发布这个链接。

答案 2 :(得分:-1)

fbsr_APP_ID cookie实际上是一个signed_request,请查看facebook官方文档如何解码签名请求验证签名并获取用户信息。您还可以查看官方php SDK源代码,了解它们如何从那里获取访​​问令牌。

答案 3 :(得分:-4)

您必须使用代码来获取实际的access_token。