Facebook身份验证:调用https://graph.facebook.com/oauth/access_token返回400错误请求

时间:2015-10-07 13:11:20

标签: .net facebook model-view-controller oauth facebook-login

尝试在mvc Web应用程序中实现facebook身份验证。

在localhost中,一切都按预期工作。在测试服务器中,我得到了

调用

时有400个错误请求

https://graph.facebook.com/oauth/access_token?client_id=xxx &安培; REDIRECT_URI = XXX &安培; client_secret = XXX &安培;代码= XXX

我正在使用从here

获得的FacebookScopedClient类

2 个答案:

答案 0 :(得分:6)

解决。 Facebook返回400个错误请求,因为它期望redirect_uri 参数在调用两者时都是相同的

https://www.facebook.com/dialog/oauth 和  https://graph.facebook.com/oauth/access_token

我正在使用网上浮动的FacebookScopedClient类的变体。

它设置redirect_uri的值context.Request.Url.OriginalString;

该字符串包含端口号,而原始URL不包含。

解决方案是在第一次调用中包含端口号,从第二次调用中删除它,或者首先从redirect_uri获取Request.Url值。

我选择了第二个选项:

  if (context.Request.Url.IsDefaultPort)
            {
                rawUrl = rawUrl.Replace(":80", ""); //patch to remove port number. 
            }

它可能不是防弹,因为可能有一个奇怪的情况":80"出现在网址的其他地方,但它对我的需求很有用。

答案 1 :(得分:1)

using System;
using System.Net;
using System.Collections.Generic;
using System.Web;
using System.Web.Helpers;
using System.Collections.Specialized;
using Newtonsoft.Json;
using System.Web.Script.Serialization;


namespace ExtensionMethods
{
    public class FacebookV2Client : DotNetOpenAuth.AspNet.Clients.OAuth2Client
    {
        private const string AuthorizationEP = "https://www.facebook.com/v2.0/dialog/oauth";
        private const string TokenEP = "https://graph.facebook.com/v2.0/oauth/access_token";
        private readonly string _appId;
        private readonly string _appSecret;

        public FacebookV2Client(string appId, string appSecret)
            : base("facebook")
        {
            this._appId = appId;
            this._appSecret = appSecret;
        }


        protected override Uri GetServiceLoginUrl(Uri returnUrl)
        {
            return new Uri(
                        AuthorizationEP
                        + "?client_id=" + this._appId
                        + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                        + "&scope=email,user_about_me"
                        + "&display=page"
                    );
        }

        protected override IDictionary<string, string> GetUserData(string accessToken)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                "https://graph.facebook.com/me?access_token=" + accessToken
            );
            dynamic data = Json.Decode(content);
            return new Dictionary<string, string> {
                {
                    "username",
                    data.email
                },
                {
                    "id",
                    data.id
                },
                {
                    "name",
                    data.name
                },
                {
                    "photo",
                    "https://graph.facebook.com/" + data.id + "/picture"
                },
                {
                    "email",
                    data.email
                }
            };
        }

        protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
        {
            WebClient client = new WebClient();
            string content = client.DownloadString(
                TokenEP
                + "?client_id=" + this._appId
                + "&client_secret=" + this._appSecret
                + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
                + "&code=" + authorizationCode
            );

            NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(content);
            if (nameValueCollection != null)
            {
                string result = nameValueCollection["access_token"];
                return result;
            }
            return null;
        }
    }
}

在AuthConfig.cs中

string facebook_appId = "Your appId";
string facebook_appSecret = "Your appSecret";

OAuthWebSecurity.RegisterClient(
    new FacebookV2Client(
        appId: facebook_appId,
        appSecret: facebook_appSecret),
        "facebook", null
);

Reference