WP8 - Facebook登录问题

3
我正在尝试使用Facebook C# SDK在Windows Phone 8上验证用户。为此,我正在遵循这里的代码:FacebookLoginPage.xaml.cs 但我面临的问题是,每当我将我的用户名和密码输入到打开以验证用户的对话框中时,我只会得到以下页面: WP8 FB Login Prob 之后,我的程序不会重定向到Landing页面,而该页面是单独的视图。我看到的其他解决方案建议隐藏WebView,但由于身份验证抽象为单个LoginAsync函数调用,因此这些解决方案并不适用。您有什么建议?

你在学习哪些教程?那个登录链接不应该在浏览器中打开! - Sahil Mittal
我正在按照这里的教程进行操作:http://facebooksdk.net/docs/phone/tutorial/ - varagrawal
那么你将无法获得你上面发布的屏幕。 - Sahil Mittal
我在本地开发机器上没有看到它。但是一个朋友从代码库中拉取了解决方案并得到了这条消息。然后我在另一台机器上运行了相同的代码,它再次给出了这个页面。 - varagrawal
3个回答

6
看起来FB已经对其重定向脚本进行了一些更改,当它检测到Windows Phone Web浏览器控件时。
C# SDK所做的是将登录页面生成为“http://www.facebook.com…”。当您在Web浏览器控件上打开此URL时,它会被重定向到“http://m.facebook.com...”,显示FB登录页面的移动版本。
以前没有问题,但最近,当FB进行重定向时,它还会从URL中删除参数"display=page"。然后发生的是,当成功登录FB时,“login_success.html”页面会在没有此参数的情况下打开。没有传递"display=page"参数,它默认为"display=touch"。不幸的是,该URL没有在URL中附加令牌字符串,因此显示第一个线程中显示的页面。
解决方法是,不要使用以下代码生成登录URL,而是修改它。
Browser.Navigate(_fb.GetLoginUrl(parameters));

ammended:

var URI = _fb.GetLoginUrl(parameters).toString().replace("www.facebook.com","m.facebook.com");
Browser.Navigate(new Uri(URI));

1
在我的项目中,我只是监听了WebView的导航事件。如果发生了这种情况,意味着用户在登录页面上做了某些事情(例如按下登录按钮)。然后,我解析了你提到的页面的URI,其中应该包含OAuth回调URL,如果正确并且结果成功,我手动重定向到正确的页面:
    //somewhere in the app
    private readonly FacebookClient _fb = new FacebookClient();

    private void webBrowser1_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
    {
        FacebookOAuthResult oauthResult;
        if (!_fb.TryParseOAuthCallbackUrl(e.Uri, out oauthResult))
        {
            return;
        }

        if (oauthResult.IsSuccess)
        {
            var accessToken = oauthResult.AccessToken;
            //you have an access token, you can proceed further 
            FBLoginSucceded(accessToken);
        }
        else
        {
            // errors when logging in
            MessageBox.Show(oauthResult.ErrorDescription);
        }
    }

如果您在异步函数中抽象记录日志,则期望其异步运行,因此事件是可以接受的。
抱歉我的英语。
完整页面的代码:
public partial class LoginPageFacebook : PhoneApplicationPage
{
    private readonly string AppId = Constants.FacebookAppId;
    private const string ExtendedPermissions = "user_birthday,email,user_photos";
    private readonly FacebookClient _fb = new FacebookClient();
    private Dictionary<string, object> facebookData = new Dictionary<string, object>();
    UserIdentity userIdentity = App.Current.Resources["userIdentity"] as UserIdentity;

    public LoginPageFacebook()
    {
        InitializeComponent();
    }

    private void webBrowser1_Loaded(object sender, RoutedEventArgs e)
    {
        var loginUrl = GetFacebookLoginUrl(AppId, ExtendedPermissions);
        webBrowser1.Navigate(loginUrl);
    }

    private Uri GetFacebookLoginUrl(string appId, string extendedPermissions)
    {
        var parameters = new Dictionary<string, object>();
        parameters["client_id"] = appId;
        parameters["redirect_uri"] = "https://www.facebook.com/connect/login_success.html";
        parameters["response_type"] = "token";
        parameters["display"] = "touch";

        // add the 'scope' only if we have extendedPermissions.
        if (!string.IsNullOrEmpty(extendedPermissions))
        {
            // A comma-delimited list of permissions
            parameters["scope"] = extendedPermissions;
        }

        return _fb.GetLoginUrl(parameters);
    }

    private void webBrowser1_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
    {
        if (waitPanel.Visibility == Visibility.Visible)
        {
            waitPanel.Visibility = Visibility.Collapsed;
            webBrowser1.Visibility = Visibility.Visible;
        }

        FacebookOAuthResult oauthResult;
        if (!_fb.TryParseOAuthCallbackUrl(e.Uri, out oauthResult))
        {
            return;
        }

        if (oauthResult.IsSuccess)
        {
            var accessToken = oauthResult.AccessToken;
            FBLoginSucceded(accessToken);
        }
        else
        {
            // user cancelled
            MessageBox.Show(oauthResult.ErrorDescription);
        }
    }

    private void FBLoginSucceded(string accessToken)
    {

        var fb = new FacebookClient(accessToken);

        fb.GetCompleted += (o, e) =>
        {
            if (e.Error != null)
            {
                Dispatcher.BeginInvoke(() => MessageBox.Show(e.Error.Message));
                return;
            }

            var result = (IDictionary<string, object>)e.GetResultData();
            var id = (string)result["id"];

            userIdentity.FBAccessToken = accessToken;
            userIdentity.FBID = id;

            facebookData["Name"] = result["first_name"];
            facebookData["Surname"] = result["last_name"];
            facebookData["Email"] = result["email"];
            facebookData["Birthday"] = DateTime.Parse((string)result["birthday"]);
            facebookData["Country"] = result["locale"];

            Dispatcher.BeginInvoke(() =>
                {
                    BitmapImage profilePicture = new BitmapImage(new Uri(string.Format("https://graph.facebook.com/{0}/picture?type={1}&access_token={2}", id, "square", accessToken)));
                    facebookData["ProfilePicture"] = profilePicture;

                    userIdentity.FBData = facebookData;
                    userIdentity.ProfilePicture = profilePicture;

                    ARLoginOrRegister();
                });
        };

        fb.GetAsync("me");
    }

    private void ARLoginOrRegister()
    {
        WebService.ARServiceClient client = new WebService.ARServiceClient();
        client.GetUserCompleted += client_GetUserCompleted;
        client.GetUserAsync((string)facebookData["Email"]);
        client.CloseAsync();
    }

    void client_GetUserCompleted(object sender, WebService.GetUserCompletedEventArgs e)
    {
        if (e.Result == null)
            NavigationService.Navigate(new Uri("/RegisterPageFacebook.xaml", UriKind.RelativeOrAbsolute));
        else if (e.Result.AccountType != (int)AccountType.Facebook)
        {
            MessageBox.Show("This account is not registered with facebook!");
            NavigationService.Navigate(new Uri("/LoginPage.xaml", UriKind.RelativeOrAbsolute));
        }
        else
        {
            userIdentity.Authenticated += userIdentity_Authenticated;
            userIdentity.FetchARSocialData((string)facebookData["Email"]);
        }

    }

    void userIdentity_Authenticated(bool success)
    {
        NavigationService.Navigate(new Uri("/MenuPage.xaml", UriKind.RelativeOrAbsolute));
    }
}

只是一个全屏覆盖显示“连接中...”和一个不确定的进度条。 当用户进入页面时,这就是他所能看到的。 当浏览器准备好并导航到外部Facebook登录网页时,第一次发出导航事件。 代码的第一部分隐藏了waitPanel并返回,因为URL不包含有效的OAuth回调。当用户按下“登录”按钮时,浏览器第二次发出“导航”事件,然后您可以再次在处理程序中显示waitPanel(我没有这样做),并在后台执行逻辑。 - Michael K. Sondej

1

在尝试所有建议的更改之前,请检查您的Facebook应用程序是否处于沙盒模式。这最终将解决您的问题。

enter image description here

如果您的Facebook应用处于沙盒模式下,则只有开发者可以使用其电子邮件地址登录。任何其他Facebook用户将会得到白色页面。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接