来自 Windows Store App (WebAuthenticationBroker.AuthenticateAsync) 的 Facebook 身份验证 (OAuth2) 在台式机上失败

Facebook authentication (OAuth2) from Windows Store App (WebAuthenticationBroker.AuthenticateAsync) fails on desktop computers

我有一个已发布的 Xamarin.Forms 应用程序。该应用程序建议用户通过多个 OAuth 身份验证提供程序(Google、Facebook、Microsoft、Yandex、Vkontakte、Mail.Ru、Odnoklassniki)进行身份验证。

在 Windows 上,通过 Facebook 进行身份验证的方式如下:

string clientID = "<client ID from facebook app settings>";

string startUri = "https://m.facebook.com/dialog/oauth/?" + 
    "client_id=" + clientID +
    "&scope=" + "email,public_profile" + 
    "&redirect_uri=" + "https://m.facebook.com/connect/login_success.html" + 
    "&state=" + Guid.NewGuid().ToString("N") + 
    "&response_type=" + "token";

WebAuthenticationBroker.AuthenticateAsync(
    WebAuthenticationOptions.None,
    new Uri(startUri),
    new Uri("https://m.facebook.com/connect/login_success.html"));

相同的原理图但具有不同的 Uris 用于其他身份验证提供程序并且工作正常。 Facebook 身份验证在 windows 手机上有效,但在 Windows 10 和 Windows 8.1 台式计算机上失败。失败场景:

  1. 出现 WebAuthenticationBroker windows。

  2. Facebook 身份验证对话框内容显示几秒钟。

  3. Facebook 身份验证对话框内容消失,取而代之的是以下文本:“我们现在无法连接到您需要的服务。请检查您的网络连接或重试稍后。”。

在我的应用程序代码的第 2 步和第 3 步之间 none 正在执行。在许多不同的计算机上也会发生同样的情况。我尝试将 Uri 从 m.facebook.com 替换为 www.facebook.com 没有效果。

WebAuthenticationBroker.AuthenticateAsync 返回的 Task<WebAuthenticationResult>IsFaulted 状态和内部异常结束:

System.AggregateException: One or more errors occurred. ---> System.Exception: Exception from HRESULT: 0x800C0503

--- End of inner exception stack trace ---

---> (Inner Exception #0) System.Exception: Exception from HRESULT: 0x800C0503<---

我应该在哪里进一步挖掘?

将此参数添加到 startUri "display=popup",因此您的代码应如下所示:

string startUri = "https://m.facebook.com/dialog/oauth/?" + 
"client_id=" + clientID +
"&display=popup" +
"&scope=" + "email,public_profile" + 
"&redirect_uri=" + "https://m.facebook.com/connect/login_success.html" + 
"&state=" + Guid.NewGuid().ToString("N") + 
"&response_type=" + "token";

显示参数的其他可能值有:async、iframe、page、popup、touch、wap。

我一直在与 Facebook SDK 支持和 Microsoft 支持密切合作解决这个问题。这很像同时从两侧受到撞击,同时试图让自己愉快。感觉自己被宠坏了,浪费了,但仍然很满足。

长话短说,我有一个解决方法,现在只用于 Facebook/Windows 桌面组合:

//We need to instruct the WebAuthenticationBroker to end the scenario
//somehow without specifying the callbackUri parameter. This is called 
//`an implicit callback Uri scenario` in which WebAuthenticationBroker
//is expecting to see this Uri for the end:
string callbackUri = WebAuthenticationBroker.GetCurrentApplicationCallbackUri().AbsoluteUri;

//So we need to instruct Facebook authentication to finally redirect to this Uri.
string startUri = "https://m.facebook.com/dialog/oauth/?" + 
    "client_id=" + clientID +
    "&scope=" + "email,public_profile" + 
    "&redirect_uri=" + callbackUri + 
    "&state=" + Guid.NewGuid().ToString("N") + 
    "&response_type=" + "token";

//The workaround is to go with the WebAuthenticationBroker.AuthenticateAsync
//overload which does not accept the callbackUri parameter.
WebAuthenticationBroker.AuthenticateAsync(
    WebAuthenticationOptions.None,
    new Uri(startUri)));

Facebook 和 Microsoft 都没有做任何事情来帮助解决这个问题,也没有提供任何合乎逻辑的解释来解释为什么这个场景必须用于 Windows 桌面。我再次提到:在 Windows Phone 8.1 / 10 上,显式回调 Uri 方案完美运行。

我必须提到,为了让 Facebook 身份验证接受这样的隐式回调 Uri,您需要将这些 Uris 包含到 Valid OAuth redirect URIs 设置中 Facebook login 应用参数。

  1. https://www.facebook.com/dialog/return/ms
  2. https://m.facebook.com/dialog/return/ms

...Facebook的又一设计杰作。啊