10

2017 년 3 월 27 일에 Facebook GRAPH API가 만료 된 후 Facebook 응용 프로그램에서 내 웹 응용 프로그램에 대한 액세스를 제공하지 않는 것으로 나타났습니다. 주로 OAuthWebSecurity이 페이스 북 그래프 API에서 로그인 상태를 가져 오지 못했습니다. 개발자 그룹에서 bug 보고서를 보았습니다. 그러나 그들은 해결책을 제시하지 못했습니다. 이 linkNopCommerce에 제공된 솔루션이 있습니다. 그러나 MVC 4에 대한 완벽한 솔루션을 얻지 못했습니다.MVC 4 웹 응용 프로그램의 페이스 북에서 외부 로그인이 작동하지 않습니다

내가 MVC4에서 솔루션을 필요로하고 OWIN 그래서 내가이 문제를 해결 어떻게 VS 2012MVC4 지원되지 않습니다 언급 그러나 그들은 시스템이 MVC 5에 접근이 link를 통과했다. 나는 지난 1 주 이후로이 문제를 겪어왔다.

주로 예외 그것은이 널 (null)뿐만 아니라 매개 변수의 IsSuccessful이 거짓과 휴식 반환 것 코드

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

의이 작품에서 일어나고있다.

페이스 북이 API의 반환 유형을 에서 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 링크를 대체하는 것입니다.

지금 당신은 모든 성공을 래퍼 클래스

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

를 사용하여

있는 authconfig

을 수정해야합니다. 페이스 북 로그인은 이전 상태로 돌아갑니다.

이전 API가 아닌이 새로운 API에 관한 새로운 문제에 직면 할 수 있지만 문제는 IP Whitelisting입니다. 이 image처럼 희망은 당신이 아무것도 필요하지 않습니다. 행복한 코딩.

5

이 솔루션을 확인하셨습니까?

는 "우리는 2017년 3월 27일 (월요일), 자신의 그래프 API 버전 2.2에 대한 페이스 북 지원 중단. 우리는 또한 원래 Nuget를 통해 설치 DotNetOpenAuth를 사용하는 . 소스 코드에서이 같은 문제로 실행 (2017년 4월 18일)

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

편집 "아래 링크에서 확인할 수 있습니다 안녕하세요, 오늘 아침에 다음 링크를 통해 온 것 그리고 그것은 나를 위해 문제를 해결했다. 그것을 시도주고 알려주세요 :)

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

코드가 사용자의 ADOConnection에서 '에 의해 제공됩니다. 그것은 링크의 4 번째 게시물입니다.

나는 내 머리카락을 잡아 당겼다. 롤

안부 인사!

+0

죄송합니다. 나는 당신의 대답을 받아 들일 수 없습니다. 'MVC 4'에서 'NopCommerce'또는 'MVC 5'가 아닌 답변을 찾고 있습니다. –

+0

Guilherme! 내가 더 많은 표를 줄 수 있으면 좋겠어. 내 것은 MVC 4이며 FacebookClient2017 클래스가 작동했습니다. 다시 한번 감사드립니다. –

+0

이 솔루션은 v2.5의 그래프 API를 사용했지만 작동했습니다. – Umair