2017-03-27 86 views
5

我們的Facebook登錄不能正常工作。我們收到的消息來自Facebook的開發者門戶網站:版本棄用Facebook Graph API v2.2

「應用名稱」當前訪問圖形API V2.2將達到 2年的生命週期結束於3月27日,2017年要確保平穩過渡,請將所有調用遷移到Graph API v2.3或更高版本。

要檢查您的應用是否會受此升級影響,您可以使用 版本升級工具。這將告訴你哪些呼叫(如果有的話)是 受此更改影響以及更新的 版本中的任何更換呼叫。如果您沒有看到任何呼叫,您的應用可能不會受到 此更改的影響。

您還可以使用我們的更改日誌查看所有 Graph API版本中的更改的完整列表。

我們正在使用ASP.NET MVC 5,我們正在使用或認證這樣的:今天

var facebookAuthenticationOptions = new FacebookAuthenticationOptions() 
      { 
       AppId = "****", 
       AppSecret = "****", 
       AuthenticationType = "Facebook", 
       SignInAsAuthenticationType = "ExternalCookie", 
       Provider = new FacebookAuthenticationProvider 
       { 
        OnAuthenticated = async ctx => ctx.Identity.AddClaim(new Claim(ClaimTypes.Email, ctx.User["email"].ToString())) 
       } 
      }; 

      facebookAuthenticationOptions.Scope.Add("email"); 

但是,我們的登錄信息的對象,爲null在ExternalLoginCallback:

 [HttpGet] 
     [AllowAnonymous] 
     [RequireHttps] 
     public async Task<ActionResult> ExternalLoginCallback(string returnUrl = null) 
     { 
      try 
      { 
       var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(); 
       if (loginInfo == null) 
       { 
        return RedirectToAction("Login"); 
       } 
... more code here... 

在Facebook Dev。門戶網站我們的API的版本是2.3

我們已經測試了多種選擇,但沒有任何結果:

Access email address in the OAuth ExternalLoginCallback from Facebook v2.4 API in ASP.NET MVC 5

Why new fb api 2.4 returns null email on MVC 5 with Identity and oauth 2?

謝謝各位大大的幫助。

+1

這裏看到的解決辦法:HTTP:// stackoverflow.com/questions/22364442/asp-net-mvc5-owin-facebook-authentication-suddenly-not-working sammy34的答案 –

+0

@MarcHägele謝謝你在跟隨你的鏈接之後,由於sammy34的回答,我能夠解決我的問題。 – Alisson

回答

9

我有同樣的問題,這是我如何設法解決它,並從Facebook獲得電子郵件。

  • 更新以下的NuGet Pacakges
    • Microsoft.Owin3.1.0-rc1版本
    • Microsoft.Owin.Security3.1.0-rc1版本
    • Microsoft.Owin.Security.Cookies3.1.0-rc1版本
    • Microsoft.Owin.Security.OAuth到版本3.1.0-rc1
    • Microsoft.Owin.Security.Facebook到版本3.1.0-rc1

然後下面的代碼添加到Identity Startup

var facebookOptions = new FacebookAuthenticationOptions() 
     { 
      AppId = "your app id", 
      AppSecret = "your app secret", 
      BackchannelHttpHandler = new FacebookBackChannelHandler(), 
      UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name", 
      Scope = { "email" } 
     }; 

     app.UseFacebookAuthentication(facebookOptions); 

這是FacebookBackChannelHandler()定義類:

using System; 
using System.Net.Http; 

public class FacebookBackChannelHandler : HttpClientHandler 
{ 
    protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(
     HttpRequestMessage request, 
     System.Threading.CancellationToken cancellationToken) 
    { 
     // Replace the RequestUri so it's not malformed 
     if (!request.RequestUri.AbsolutePath.Contains("/oauth")) 
     { 
      request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token")); 
     } 

     return await base.SendAsync(request, cancellationToken); 
    } 
} 
+0

這是完全完整的解決方案,我已經實施了,好點 – chemitaxis

+0

這是令人難以置信的......糟糕的不好的OWIN團隊......會嘗試,稍後再回來,我的應用程序已經死了,因爲這 –

+0

@ user3012760是必需的包現實化?因爲西班牙語的RC1軟件包仍然不可用。 –

0

只需更新與OWIN相關的所有參考 最新的OWIN版本是3.1.0rc1。

這修復了登錄按鈕,而不是電子郵件,我無法弄清楚這些問題。

+0

它專門修復了登錄按鈕,因爲Facebook已將身份驗證令牌請求的響應類型更新爲MS Owin 3.0.1無法處理的JSON。 –

+1

我已更新到rc1並修復。但我需要插入一個答案 – chemitaxis

+0

的代碼很好,我也會看看。 – HolloW

0

如果你不能更新OWIn因爲語言包(因爲我的情況),你可以

  1. 修改身份啓動類代碼:

    var facebookOptions = new FacebookAuthenticationOptions() 
    { 
        AppId = "your app id", 
        AppSecret = "your app secret", 
        BackchannelHttpHandler = new FacebookBackChannelHandler(), 
        UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name", 
        Scope = { "email" } 
    }; 
    
    app.UseFacebookAuthentication(facebookOptions); 
    
  2. 這是FacebookBackChannelHandler()的定義類:

    public class FacebookBackChannelHandler : HttpClientHandler 
    { 
        protected override async System.Threading.Tasks.Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) 
        { 
         if (!request.RequestUri.AbsolutePath.Contains("/oauth")) 
         { 
          request.RequestUri = new Uri(request.RequestUri.AbsoluteUri.Replace("?access_token", "&access_token")); 
         } 
    
         var result = await base.SendAsync(request, cancellationToken); 
         if (!request.RequestUri.AbsolutePath.Contains("/oauth")) 
         { 
          return result; 
         } 
    
         var content = await result.Content.ReadAsStringAsync(); 
         var facebookOauthResponse = JsonConvert.DeserializeObject<FacebookOauthResponse>(content); 
    
         var outgoingQueryString = HttpUtility.ParseQueryString(string.Empty); 
         outgoingQueryString.Add(nameof(facebookOauthResponse.access_token), facebookOauthResponse.access_token); 
         outgoingQueryString.Add(nameof(facebookOauthResponse.expires_in), facebookOauthResponse.expires_in + string.Empty); 
         outgoingQueryString.Add(nameof(facebookOauthResponse.token_type), facebookOauthResponse.token_type); 
         var postdata = outgoingQueryString.ToString(); 
    
         var modifiedResult = new HttpResponseMessage(HttpStatusCode.OK) 
         { 
          Content = new StringContent(postdata) 
         }; 
    
         return modifiedResult; 
        } 
    } 
    
    private class FacebookOauthResponse 
    { 
        public string access_token { get; set; } 
        public long expires_in { get; set; } 
        public string token_type { get; set; } 
    }