Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/facebook/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net DotNetOpenAuth CTP-Facebook错误请求_.net_Facebook_Dotnetopenauth - Fatal编程技术网

.net DotNetOpenAuth CTP-Facebook错误请求

.net DotNetOpenAuth CTP-Facebook错误请求,.net,facebook,dotnetopenauth,.net,Facebook,Dotnetopenauth,我正在尝试使用CTP通过OAuth2.0连接Facebook 我可以让Facebook的初始请求正常工作,但当它返回时,我们会呼叫: // Where null will become an HttpRequestInfo object client.ProcessUserAuthorization(null); 我得到: 远程服务器返回错误:(400)请求错误 我对最初的代码库并没有做太多的工作;只需将可选值设置为null(我们仍然使用.NET3.5)。任何线索都将不胜感激 而且,我想这对安

我正在尝试使用CTP通过OAuth2.0连接Facebook

我可以让Facebook的初始请求正常工作,但当它返回时,我们会呼叫:

// Where null will become an HttpRequestInfo object
client.ProcessUserAuthorization(null);
我得到:

远程服务器返回错误:(400)请求错误

我对最初的代码库并没有做太多的工作;只需将可选值设置为null(我们仍然使用.NET3.5)。任何线索都将不胜感激

而且,我想这对安德鲁来说更像是一个问题;是否有一个论坛/博客,或任何地方,将定期更新这些东西?知道一些事情会很好:

  • 使用OAuth 2.0的DotNetOpenAuth的计划发布日期
  • .NET4.0是否是先决条件

  • 无论如何,任何建议都是非常受欢迎的

    我发现编写自己的实现比使用DNOA花费的时间更少。这不是很难,尽管我还没有对代码进行彻底的安全检查;我想这是一个重要的警告


    这可能没什么帮助,但我发现一天只花了1/2的时间就可以完成工作。

    在遇到这个问题后,我编写了自己的代码进行授权,并获取用户的详细信息。另一种方法是使用。作为其他想在那里做自己的人的开始,下面是我是如何做到的。请注意,我没有调查错误案例

    首先,关于它的工作原理(很简单!)

    我是这样消费的:

    private static readonly FacebookClient facebookClient = new FacebookClient();
    public ActionResult LoginWithFacebook()
    {
        var result = facebookClient.Authorize();
        if (result == FacebookAuthorisationResult.RequestingCode)
        {
            //The client will have already done a Response.Redirect
            return View();
        } else if (result == FacebookAuthorisationResult.Authorized)
        {
            var user = facebookClient.GetCurrentUser();
        }
        return Redirect("/");
    }
    
    // Get basic information for this user
    var basicInfoUrl = string.Format("https://graph.facebook.com/me?access_token={0}", Uri.EscapeDataString(accessToken.TokenString));
    var json = new WebClient().DownloadString(basicInfoUrl);
    
    和客户端代码:

    using System;
    using System.IO;
    using System.Net;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Json;
    using System.Text;
    using System.Web;
    
    namespace Web.Services
    {
        public enum FacebookAuthorisationResult
        {
            Denied,
            Authorized,
            RequestingCode
        }
        public class FacebookClient
        {
            private const String SESSION_NAME_TOKEN = "UserFacebookToken";
            public FacebookClient()
            {
                TokenEndpoint = new Uri("https://graph.facebook.com/oauth/access_token");
                AuthorizationEndpoint = new Uri("https://graph.facebook.com/oauth/authorize");
                MeGraphEndpoint = new Uri("https://graph.facebook.com/me");
                ClientIdentifier = "xxxxxxxxxxxxxxxxxx";
                Secret = "xxxxxxxxxxxx";
                LocalSubDomain = "local.xxxxxxx.com";
            }
    
            public Uri TokenEndpoint { get; set; }
            public Uri AuthorizationEndpoint { get; set; }
            public Uri MeGraphEndpoint { get; set; }
            public String Secret { get; set; }
            public String ClientIdentifier { get; set; }
            private String LocalSubDomain { get; set; }
    
    
            public FacebookAuthorisationResult Authorize()
            {
                var errorReason = HttpContext.Current.Request.Params["error_reason"];
                var userDenied = errorReason != null;
                if (userDenied)
                    return FacebookAuthorisationResult.Denied;
                var verificationCode = HttpContext.Current.Request.Params["code"];
                var redirectUrl = GetResponseUrl(HttpContext.Current.Request.Url);
                var needToGetVerificationCode = verificationCode == null;
                if (needToGetVerificationCode)
                {
                    var url = AuthorizationEndpoint + "?" +
                              "client_id=" + ClientIdentifier + "&" +
                              "redirect_uri=" + redirectUrl;
                    HttpContext.Current.Response.Redirect(url);
                    return FacebookAuthorisationResult.RequestingCode;
                }
                var token = ExchangeCodeForToken(verificationCode, redirectUrl);
                HttpContext.Current.Session[SESSION_NAME_TOKEN] = token;
                return FacebookAuthorisationResult.Authorized;
            }
            public Boolean IsCurrentUserAuthorized()
            {
                return HttpContext.Current.Session[SESSION_NAME_TOKEN] != null;
            }
            public FacebookGraph GetCurrentUser()
            {
                var token = HttpContext.Current.Session[SESSION_NAME_TOKEN];
                if (token == null)
                    return null;
                var url = MeGraphEndpoint + "?" +
                          "access_token=" + token;
                var request = WebRequest.CreateDefault(new Uri(url));
                using (var response = request.GetResponse())
                {
                    using (var responseStream = response.GetResponseStream())
                    {
                        using (var responseReader = new StreamReader(responseStream))
                        {
                            var responseText = responseReader.ReadToEnd();
                            var user =  FacebookGraph.Deserialize(responseText);
                            return user;
                        }
                    }
                }
            }
            private String ExchangeCodeForToken(String code, Uri redirectUrl)
            {
                var url = TokenEndpoint + "?" +
                          "client_id=" + ClientIdentifier + "&" +
                          "redirect_uri=" + redirectUrl + "&" +
                          "client_secret=" + Secret + "&" +
                          "code=" + code;
                var request = WebRequest.CreateDefault(new Uri(url));
                using (var response = request.GetResponse())
                {
                    using (var responseStream = response.GetResponseStream())
                    {
                        using (var responseReader = new StreamReader(responseStream))
                        {
                            var responseText = responseReader.ReadToEnd();
                            var token = responseText.Replace("access_token=", "");
                            return token;
                        }
                    }
                }
            }
            private Uri GetResponseUrl(Uri url)
            {
                var urlAsString = url.ToString();
                var doesUrlContainQuestionMark = urlAsString.Contains("?");
                if (doesUrlContainQuestionMark)
                {
                    // Remove any parameters. Apparently Facebook does not support state: http://forum.developers.facebook.net/viewtopic.php?pid=255231
                    // If you do not do this, you will get 'Error validating verification code'
                    urlAsString = urlAsString.Substring(0, urlAsString.IndexOf("?"));
                }
                var replaceLocalhostWithSubdomain = url.Host == "localhost";
                if (!replaceLocalhostWithSubdomain)
                    return new Uri(urlAsString);
                // Facebook does not like localhost, you can only use the configured url. To get around this, log into facebook
                // and set your Site Domain setting, ie happycow.com. 
                // Next edit C:\Windows\System32\drivers\etc\hosts, adding the line: 
                // 127.0.0.1       local.happycow.cow
                // And lastly, set LocalSubDomain to local.happycow.cow
                urlAsString = urlAsString.Replace("localhost", LocalSubDomain);
                return new Uri(urlAsString);
            }
        }
        [DataContract]
        public class FacebookGraph
        {
            private static DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(FacebookGraph));
                // Note: Changed from int32 to string based on Antonin Jelinek advise of an overflow
            [DataMember(Name = "id")]
            public string Id { get; set; }
    
            [DataMember(Name = "name")]
            public string Name { get; set; }
    
            [DataMember(Name = "first_name")]
            public string FirstName { get; set; }
    
            [DataMember(Name = "last_name")]
            public string LastName { get; set; }
    
            [DataMember(Name = "link")]
            public Uri Link { get; set; }
    
            [DataMember(Name = "birthday")]
            public string Birthday { get; set; }
    
            public static FacebookGraph Deserialize(string json)
            {
                if (String.IsNullOrEmpty(json))
                {
                    throw new ArgumentNullException("json");
                }
    
                return Deserialize(new MemoryStream(Encoding.UTF8.GetBytes(json)));
            }
    
            public static FacebookGraph Deserialize(Stream jsonStream)
            {
                if (jsonStream == null)
                {
                    throw new ArgumentNullException("jsonStream");
                }
    
                return (FacebookGraph)jsonSerializer.ReadObject(jsonStream);
            }
        }
    
    
    }
    

    Iain的解决方案终于成为了我的解决方案

    对于未来的实现者,有一点需要注意——Facebook ID属性现在似乎超过了Int32类型的容量。您可能需要在FacebookGraph类中对此进行更改,我使用了纯字符串


    谢谢伊恩,你的代码真的帮助了我

    在花了很长一段时间升级DotNetOpenAuth后,我也没有遇到任何连接到Facebook的运气,我也在ASP.NET MVC应用程序中编写了一些代码来支持Facebook登录

    首先,像这样的代码应该放在控制器的某个地方

    // You call this action to initiate the process with Facebook
    public ActionResult FacebookLogIn()
    {
        return CreateFacebookClient().RequestAuthorisation();
    }
    
    // Facebook will call you back here
    public ActionResult FacebookAuthorisationResponse()
    {
        var facebookClient = CreateFacebookClient();
        var authorisationResponse = facebookClient.HandleAuthorisationResponse();
    
        if (authorisationResponse.IsSuccess)
        {
            var accessToken = authorisationResponse.AccessToken;
    
            // TODO do whatever you want to do with your access token here
    
            return Redirect("SomeUrl");
        }
    
        // TODO handle the error somehow
        return Content(authorisationResponse.ErrorMessage);
    }
    
    private FacebookClient CreateFacebookClient()
    {
        const string clientId = "xxxxxxxxxxxxxxx";
        const string appSecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
    
        var redirectUrl = Url.Action("FacebookAuthorisationResponse", null, null, "http");
    
        return new FacebookClient(clientId, appSecret, redirectUrl);
    }
    
    这就是你需要做的所有代码。一旦您拥有该访问令牌,您可以执行以下操作:

    private static readonly FacebookClient facebookClient = new FacebookClient();
    public ActionResult LoginWithFacebook()
    {
        var result = facebookClient.Authorize();
        if (result == FacebookAuthorisationResult.RequestingCode)
        {
            //The client will have already done a Response.Redirect
            return View();
        } else if (result == FacebookAuthorisationResult.Authorized)
        {
            var user = facebookClient.GetCurrentUser();
        }
        return Redirect("/");
    }
    
    // Get basic information for this user
    var basicInfoUrl = string.Format("https://graph.facebook.com/me?access_token={0}", Uri.EscapeDataString(accessToken.TokenString));
    var json = new WebClient().DownloadString(basicInfoUrl);
    
    这里是支持上面相对简单的东西的代码。您可以将所有这些内容转储到项目中的一个文件中:

    // Drew Noakes, http://drewnoakes.com
    // Created 08/08/2012 22:41
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Web;
    using System.Web.Mvc;
    
    namespace DrewNoakes.Facebook.Mvc
    {
        public sealed class FacebookClient
        {
            private readonly string _clientId;
            private readonly string _appSecret;
            private readonly string _authorisationResponseUrl;
    
            public IFacebookClientStateManager StateManager { get; set; }
    
            public FacebookClient(string clientId, string appSecret, string authorisationResponseUrl)
            {
                _clientId = clientId;
                _appSecret = appSecret;
                _authorisationResponseUrl = authorisationResponseUrl;
    
                StateManager = MemoryStateManager.Instance;
            }
    
            public ActionResult RequestAuthorisation(string[] permissions = null)
            {
                // First step is to redirect the visitor's browser to Facebook
    
                var state = StateManager.GetState();
    
                var url = string.Format("https://www.facebook.com/dialog/oauth?client_id={0}&redirect_uri={1}&scope={2}&state={3}",
                    _clientId, Uri.EscapeDataString(_authorisationResponseUrl), permissions == null ? string.Empty : string.Join(",", permissions), state);
    
                return new RedirectResult(url, permanent: false);
            }
    
            public AuthorisationResponse HandleAuthorisationResponse()
            {
                var queryString = HttpContext.Current.Request.QueryString;
    
                // Ensure returned state is expected
                if (!StateManager.IsValidState(queryString["state"]))
                    return AuthorisationResponse.Error("Invalid state");
    
                // TODO handle case where user declined: YOUR_REDIRECT_URI?error_reason=user_denied&error=access_denied&error_description=The+user+denied+your+request.&state=YOUR_STATE_VALUE
    
                var code = queryString["code"];
                var url = string.Format("https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&code={3}&client_secret={2}",
                    _clientId, Uri.EscapeDataString(_authorisationResponseUrl), _appSecret, Uri.EscapeDataString(code));
    
                var client = new WebClient { Proxy = null };
                var responseBody = client.DownloadString(url);
    
                // HTTP 200: access_token=USER_ACCESS_TOKEN&expires=NUMBER_OF_SECONDS_UNTIL_TOKEN_EXPIRES
                // HTTP 400: TODO handle JSON error reponse: { "error": { "type": "OAuthException", "message": "Error validating verification code." } }
    
                var response = HttpUtility.ParseQueryString(responseBody);
                var accessToken = response["access_token"];
                var expiresSecondsString = response["expires"];
    
                int expiresSeconds;
                if (!int.TryParse(expiresSecondsString, out expiresSeconds))
                    return AuthorisationResponse.Error("Unable to parse expiration time");
                var expiresAtUtc = DateTime.UtcNow.AddSeconds(expiresSeconds);
    
                return AuthorisationResponse.Success(accessToken, expiresAtUtc);
            }
        }
    
        public class AuthorisationResponse
        {
            public bool IsSuccess { get; private set; }
            public AccessToken AccessToken { get; private set; }
            public string ErrorMessage { get; private set; }
    
            private AuthorisationResponse() { }
    
            public static AuthorisationResponse Error(string errorMessage)
            {
                return new AuthorisationResponse { IsSuccess = false, ErrorMessage = errorMessage };
            }
    
            public static AuthorisationResponse Success(string accessToken, DateTime expiresAtUtc)
            {
                return new AuthorisationResponse { IsSuccess = true, AccessToken = new AccessToken(accessToken, expiresAtUtc) };
            }
        }
    
        public struct AccessToken
        {
            public string TokenString { get; private set; }
            public DateTime ExpiresAtUtc { get; private set; }
    
            public AccessToken(string tokenString, DateTime expiresAtUtc)
                : this()
            {
                if (tokenString == null)
                    throw new ArgumentNullException("tokenString");
                TokenString = tokenString;
                ExpiresAtUtc = expiresAtUtc;
            }
        }
    
        public interface IFacebookClientStateManager
        {
            string GetState();
    
            bool IsValidState(string state);
        }
    
        /// <summary>
        /// The default implementation of <see cref="IFacebookClientStateManager"/>.
        /// </summary>
        public sealed class MemoryStateManager : IFacebookClientStateManager
        {
            private static readonly IFacebookClientStateManager _instance = new MemoryStateManager();
    
            public static IFacebookClientStateManager Instance
            {
                get { return _instance; }
            }
    
            private readonly Dictionary<string, DateTime> _stateTimes = new Dictionary<string, DateTime>();
    
            public string GetState()
            {
                var state = Guid.NewGuid().ToString("N");
                _stateTimes[state] = DateTime.UtcNow;
                return state;
            }
    
            public bool IsValidState(string state)
            {
                var isValid = _stateTimes.Remove(state);
    
                // Remove any keys that have not been accessed within a given period
                var staleKeys = _stateTimes.Where(pair => pair.Value < DateTime.UtcNow.AddMinutes(-30)).Select(pair => pair.Key).ToList();
    
                foreach (var staleKey in staleKeys)
                    _stateTimes.Remove(staleKey);
    
                return isValid;
            }
        }
    }
    
    //Drew Noakes,http://drewnoakes.com
    //已创建2012年8月8日22:41
    使用制度;
    使用System.Collections.Generic;
    使用System.Linq;
    Net系统;
    使用System.Web;
    使用System.Web.Mvc;
    命名空间DrewNoakes.Facebook.Mvc
    {
    公共密封类FacebookClient
    {
    私有只读字符串\u clientId;
    私有只读字符串\u appSecret;
    私有只读字符串_authorizationresponseUrl;
    public IFacebookClientStateManager状态管理器{get;set;}
    public FacebookClient(字符串clientId、字符串appSecret、字符串授权ResponseUrl)
    {
    _clientId=clientId;
    _appSecret=appSecret;
    _授权响应EURL=授权响应EURL;
    StateManager=MemoryStateManager.Instance;
    }
    public ActionResult RequestAuthorization(字符串[]权限=null)
    {
    //第一步是将访问者的浏览器重定向到Facebook
    var state=StateManager.GetState();
    var url=string.Format(“https://www.facebook.com/dialog/oauth?client_id={0}&redirect_uri={1}&scope={2}&state={3}“,
    _clientId,Uri.EscapeDataString(_AuthorizationResponseUrl),权限==null?字符串。空:字符串。连接(“,”,权限),状态);
    返回新的重定向结果(url,永久:false);
    }
    公共授权响应手册授权响应()
    {
    var queryString=HttpContext.Current.Request.queryString;
    //确保返回的状态是预期的
    如果(!StateManager.IsValidState(queryString[“state”]))
    返回授权响应。错误(“无效状态”);
    //TODO处理用户拒绝的情况:您的\重定向\ URI?错误\原因=用户\拒绝&错误=访问\拒绝&错误\描述=用户+拒绝+您的请求。&状态=您的\状态\值
    var代码=查询字符串[“代码”];
    var url=string.Format(“https://graph.facebook.com/oauth/access_token?client_id={0}&redirect_uri={1}&code={3}&client_secret={2}”,
    _clientId,Uri.EscapeDataString(_authorizationresponseUrl),_appSecret,Uri.EscapeDataString(code));
    var client=newwebclient{Proxy=null};
    var responseBody=client.DownloadString(url);
    //HTTP 200:access\u token=用户\u access\u token&expires=在\u token\u过期之前的\u秒数\u
    //HTTP 400:TODO处理JSON错误响应:{“错误”:{“类型”:“OAutheException”,“消息”:“验证验证代码时出错”。}
    var response=HttpUtility.ParseQueryString(responseBody);
    var accessToken=响应[“访问令牌”];
    var expiresSecondsString=响应[“expires”];
    int到期秒;
    如果(!int.TryParse(expiresSecondsString,out expiresSeconds))
    返回authorizationresponse.Error(“无法分析过期时间”);
    var expiresautc=DateTime.UtcNow.AddSeconds(expiresSeconds);
    返回授权响应。成功(accessToken,ExpiresAuthc);
    }
    }
    公共类授权响应
    {
    public bool issucess{get;private set;}
    公共访问令牌访问令牌{get;private set;}
    公共字符串错误消息{get;private set;}
    私人授权响应(){}
    公共静态授权响应错误(字符串错误消息)
    {
    返回新的授权响应{IsSuccess=false,ErrorMessage=ErrorMessage};
    }
    公共静态授权响应