10

我注意到Facebook 2017年3月27日API过期后,我的Facebook应用程序未提供访问我的Web应用程序的权限。 主要是OAuthWebSecurity未能从facebook图形API获取登录状态,我已经通过开发人员组中的bug报告。但他们没有提供解决方案。我在link中找到了针对NopCommerce的解决方案。然而我没有得到任何完美的解决方案MVC 4外部登录不适用于MVC中的Facebook 4 webapplication

我曾经使用过此link他们系统在MVC 5接近,但是我需要在MVC4解决方案,并提到OWINVS 2012 那么,如何解决这个问题支持MVC4不见了。自从最近1周以来我一直在经历这个问题。

主要的例外是发生在这段代码

AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl })); 

它返回IsSuccessful为假,其余参数都是空为好。

我已经研究过Facebook已经将API string的返回类型更改为JSON那么如何开发我的代码来准确获取那些JSON。谢谢。

更新: 这个问题仍然没有答案。任何人在这里帮助我。

回答

1

根据Previous Answer我得到了一个解决方案。在MVC4大家写下他们的AppIDSecurityCode。由于facebook GRAPH API的变化,以前的链接被破坏。因此,每个人都需要更改RegisterFacebookClient。但是这个类是.Net库中的一个密封类,所以任何人都不能扩展或覆盖它。因此我们需要使用wrapper类。让我们看看我的包装类是FacebookClientV2Dot3所以我的课会

using System; 
using System.Collections.Generic; 
using System.Collections.Specialized; 
using System.IO; 
using System.Linq; 
using System.Net; 
using System.Text; 
using System.Web; 
using DotNetOpenAuth.AspNet.Clients; 
using Newtonsoft.Json; 

public class FacebookClientV2Dot3 : OAuth2Client 
{ 
    #region Constants and Fields 

    /// <summary> 
    /// The authorization endpoint. 
    /// </summary> 
    private const string AuthorizationEndpoint = "https://www.facebook.com/dialog/oauth"; 

    /// <summary> 
    /// The token endpoint. 
    /// </summary> 
    private const string TokenEndpoint = "https://graph.facebook.com/oauth/access_token"; 

    /// <summary> 
    /// The user info endpoint. 
    /// </summary> 
    private const string UserInfoEndpoint = "https://graph.facebook.com/me"; 

    /// <summary> 
    /// The app id. 
    /// </summary> 
    private readonly string _appId; 

    /// <summary> 
    /// The app secret. 
    /// </summary> 
    private readonly string _appSecret; 

    /// <summary> 
    /// The requested scopes. 
    /// </summary> 
    private readonly string[] _requestedScopes; 

    #endregion 

    /// <summary> 
    /// Creates a new Facebook OAuth2 client, requesting the default "email" scope. 
    /// </summary> 
    /// <param name="appId">The Facebook App Id</param> 
    /// <param name="appSecret">The Facebook App Secret</param> 
    public FacebookClient(string appId, string appSecret) 
     : this(appId, appSecret, new[] { "email" }) { } 

    /// <summary> 
    /// Creates a new Facebook OAuth2 client. 
    /// </summary> 
    /// <param name="appId">The Facebook App Id</param> 
    /// <param name="appSecret">The Facebook App Secret</param> 
    /// <param name="requestedScopes">One or more requested scopes, passed without the base URI.</param> 
    public FacebookClient(string appId, string appSecret, params string[] requestedScopes) 
     : base("facebook") 
    { 
     if (string.IsNullOrWhiteSpace(appId)) 
      throw new ArgumentNullException("appId"); 

     if (string.IsNullOrWhiteSpace(appSecret)) 
      throw new ArgumentNullException("appSecret"); 

     if (requestedScopes == null) 
      throw new ArgumentNullException("requestedScopes"); 

     if (requestedScopes.Length == 0) 
      throw new ArgumentException("One or more scopes must be requested.", "requestedScopes"); 

     _appId = appId; 
     _appSecret = appSecret; 
     _requestedScopes = requestedScopes; 
    } 

    protected override Uri GetServiceLoginUrl(Uri returnUrl) 
    { 
     var state = string.IsNullOrEmpty(returnUrl.Query) ? string.Empty : returnUrl.Query.Substring(1); 

     return BuildUri(AuthorizationEndpoint, new NameValueCollection 
       { 
        { "client_id", _appId }, 
        { "scope", string.Join(" ", _requestedScopes) }, 
        { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, 
        { "state", state }, 
       }); 
    } 

    protected override IDictionary<string, string> GetUserData(string accessToken) 
    { 
     var uri = BuildUri(UserInfoEndpoint, new NameValueCollection { { "access_token", accessToken } }); 

     var webRequest = (HttpWebRequest)WebRequest.Create(uri); 

     using (var webResponse = webRequest.GetResponse()) 
     using (var stream = webResponse.GetResponseStream()) 
     { 
      if (stream == null) 
       return null; 

      using (var textReader = new StreamReader(stream)) 
      { 
       var json = textReader.ReadToEnd(); 
       var extraData = JsonConvert.DeserializeObject<Dictionary<string, object>>(json); 
       var data = extraData.ToDictionary(x => x.Key, x => x.Value.ToString()); 

       data.Add("picture", string.Format("https://graph.facebook.com/{0}/picture", data["id"])); 

       return data; 
      } 
     } 
    } 

    protected override string QueryAccessToken(Uri returnUrl, string authorizationCode) 
    { 
     var uri = BuildUri(TokenEndpoint, new NameValueCollection 
       { 
        { "code", authorizationCode }, 
        { "client_id", _appId }, 
        { "client_secret", _appSecret }, 
        { "redirect_uri", returnUrl.GetLeftPart(UriPartial.Path) }, 
       }); 

     var webRequest = (HttpWebRequest)WebRequest.Create(uri); 
     string accessToken = null; 
     HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse(); 

     // handle response from FB 
     // this will not be a url with params like the first request to get the 'code' 
     Encoding rEncoding = Encoding.GetEncoding(response.CharacterSet); 

     using (StreamReader sr = new StreamReader(response.GetResponseStream(), rEncoding)) 
     { 
      var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); 
      var jsonObject = serializer.DeserializeObject(sr.ReadToEnd()); 
      var jConvert = JsonConvert.DeserializeObject(JsonConvert.SerializeObject(jsonObject)); 

      Dictionary<string, object> desirializedJsonObject = JsonConvert.DeserializeObject<Dictionary<string, object>>(jConvert.ToString()); 
      accessToken = desirializedJsonObject["access_token"].ToString(); 
     } 
     return accessToken; 
    } 

    private static Uri BuildUri(string baseUri, NameValueCollection queryParameters) 
    { 
     var keyValuePairs = queryParameters.AllKeys.Select(k => HttpUtility.UrlEncode(k) + "=" + HttpUtility.UrlEncode(queryParameters[k])); 
     var qs = String.Join("&", keyValuePairs); 

     var builder = new UriBuilder(baseUri) { Query = qs }; 
     return builder.Uri; 
    } 

    /// <summary> 
    /// Facebook works best when return data be packed into a "state" parameter. 
    /// This should be called before verifying the request, so that the url is rewritten to support this. 
    /// </summary> 
    public static void RewriteRequest() 
    { 
     var ctx = HttpContext.Current; 

     var stateString = HttpUtility.UrlDecode(ctx.Request.QueryString["state"]); 
     if (stateString == null || !stateString.Contains("__provider__=facebook")) 
      return; 

     var q = HttpUtility.ParseQueryString(stateString); 
     q.Add(ctx.Request.QueryString); 
     q.Remove("state"); 

     ctx.RewritePath(ctx.Request.Path + "?" + q); 
    } 
} 

看吧,你我有取代由较新版本的链接的所有API链接。

现在,您需要修改

AuthConfig

只需使用一个包装类

OAuthWebSecurity.RegisterClient(new FacebookClientV2Dot3("AppID", "HassedPassword")); 

然后,所有的成功。你的Facebook登录将回到以前的状态。

但是,您可能会面临有关此新API而不是以前的API的新问题,问题是IP Whitelisting。像这样image。希望你只会需要这个。快乐的编码。

5

您是否检查了此解决方案?

“我们遇到了在星期一,2017年3月27日,当他们的图形API v2.2的Facebook的不再支持。 我们还利用DotNetOpenAuth,它最初是通过安装的NuGet该源代码同样的问题可在下面的链接”

FacebookApplication.VerifyAuthentication(_httpContext, GenerateLocalCallbackUri()) return null on Facebook

编辑(2017年4月18日): 你好,我已经遇到下列链接今天早上来了,它解决了这个问题对我来说。给它尝试,让我知道:)

https://github.com/DotNetOpenAuth/DotNetOpenAuth/issues/397

的代码是由用户的ADOConnection“提供。这是链接中的第4篇文章。

我在这拉着我的头发。大声笑

最好的问候!

+0

对不起!我无法接受你的回答。我正在寻找'MVC 4'的答案不是'NopCommerce'或'MVC 5' –

+0

非常感谢Guilherme!我希望我能给你更多的选票。我的MVC 4和你的链接FacebookClient2017类工作。再次感谢。 –

+0

尽管我使用的是图形api的v2.5,但此解决方案仍有效 – Umair

相关问题