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

相關問題