首页 文章

如何在Xamarin.Forms中登录facebook

提问于
浏览
45

我想制作一个Xamarin.Forms项目,目标是iOs,Android和Windows Phone .

我的应用需要使用Facebook验证用户身份 .

我应该独立实现每个平台的登录,还是使用手动流程? https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0

我更喜欢单一的登录流程实现,并在所有平台上使用它 .

如何才能获得facebook登录流程的单一实现?

6 回答

  • 0

    我已经创建了一个示例项目来展示如何使用本机Facebook组件创建Facebook登录,而不是通过像这里建议的解决方案那样的webview . 你可以在这个地址看看:

    https://github.com/IdoTene/XamarinFormsNativeFacebook

  • 9

    IOS 8: 对于那些正在使用@NovaJoe代码并且卡在视图上的人,请将以下代码添加到变通方法中:

    bool hasShown;
    
        public override void ViewDidAppear(bool animated)
        {
            if (!hasShown)
            {
                hasShown = true;
    
                // the rest of @novaJoe code
            }
    
        }
    
  • 5

    这是一个很好的Xamarin.Forms身份验证示例 . 代码中的文档很好 . 它使用webview呈现登录屏幕,但您可以选择所需的登录类型 . 它还保存用户令牌,因此他不必继续重新登录 .

    https://github.com/rlingineni/Xamarin.Forms_Authentication

  • 20

    您可以使用Xamarin.SocialXamarin.Auth . 无论平台是什么,它都允许使用相同的api .

    截至目前,这些库还不是PCL,但您仍然可以从共享资产项目中使用它们,或者在界面中抽象您需要的API并使用 DependencyService 或任何其他DI容器注入 .

  • 102

    UPDATE (10/24/17): 虽然这种做事方式在几年前还可以,但我现在强烈主张使用本机UI进行身份验证,而不是此处显示的webview方法 . Auth0是使用各种身份提供商完成应用程序本机UI登录的好方法:https://auth0.com/docs/quickstart/native/xamarin

    EDIT: 我终于把sample for this on Gihub

    我发了一个答案on the Xamarin Forums.我会在这里重复一遍 .

    让我们从应用程序的核心 Xamarin.Forms PCL project 开始 . 你的 App 类看起来像这样:

    namespace OAuth2Demo.XForms
    {
        public class App
        {
            static NavigationPage _NavPage;
    
            public static Page GetMainPage ()
            {
                var profilePage = new ProfilePage();
    
                _NavPage = new NavigationPage(profilePage);
    
                return _NavPage;
            }
    
            public static bool IsLoggedIn {
                get { return !string.IsNullOrWhiteSpace(_Token); }
            }
    
            static string _Token;
            public static string Token {
                get { return _Token; }
            }
    
            public static void SaveToken(string token)
            {
                _Token = token;
            }
    
            public static Action SuccessfulLoginAction
            {
                get {
                    return new Action (() => {
                        _NavPage.Navigation.PopModalAsync();
                    });
                }
            }
        }
    }
    

    首先要注意的是 GetMainPage() 方法 . 这告诉app应该在启动时首先加载哪个屏幕 .

    我们还有一个简单的属性和方法来存储从auth服务返回的 Token ,以及一个简单的 IsLoggedIn 属性 .

    还有一个Action属性;我在这里停留的东西是为了让平台实现能够执行Xamarin.Forms导航操作 . 稍后会详细介绍 .

    你'll also notice some red in your IDE because we haven' t创建了 ProfilePage 类 . 所以,让我们这样做 .

    Xamarin.Forms PCL project 中创建一个非常简单的 ProfilePage 类 . 我们甚至不打算用它做任何事情因为这取决于你的特殊需要 . 为了简化此示例,它将包含一个标签:

    namespace OAuth2Demo.XForms
    {
        public class ProfilePage : BaseContentPage
        {
            public ProfilePage ()
            {
                Content = new Label () {
                    Text = "Profile Page", 
                    VerticalOptions = LayoutOptions.CenterAndExpand,
                    HorizontalOptions = LayoutOptions.CenterAndExpand, 
                };
            }
        }
    }
    

    同样,你的IDE中可能会有一些红色,因为我们似乎错过了 BaseContentPage 类 . BaseContentPage 类的唯一目的是确保在用户登录之前不会显示任何应用程序的屏幕 . (在这个简化的演示中,我们每次运行应用程序时都需要重新登录 . -world app,你'd be storing the authenticated user info to the device'的钥匙串,这将消除在每个应用程序启动时登录的需要 . )

    Xamarin.Forms PCL project 中创建一个 BaseContentPage 类:

    namespace OAuth2Demo.XForms
    {
        public class BaseContentPage : ContentPage
        {
            protected override void OnAppearing ()
            {
                base.OnAppearing ();
    
                if (!App.IsLoggedIn) {
                    Navigation.PushModalAsync(new LoginPage());
                }
            }
        }
    }
    

    这里有一些有趣的事情:

    • 我们正在覆盖 OnAppearing() 方法,类似于iOS UIViewController中的ViewWillAppear方法 . 您可以在此处执行任何您希望在屏幕出现之前立即运行的代码 .

    • 我们唯一没有're doing in this method is checking to see if the user is logged in. If they'然后我们执行 modal push 到一个名为 LoginPage 的类 . 如果您只是一个视图,它将用户从正常的应用程序流中移出来执行某些特殊任务;在我们的例子中,执行登录 .

    那么,让我们在_2835867中创建 LoginPage 类:

    namespace OAuth2Demo.XForms
    {
        public class LoginPage : ContentPage
        {
    
        }
    }
    

    等等......为什么这堂课没有身体???

    因为我们在 LoginPage 类中需要任何类型的实现 . 我知道这看起来很奇怪,但请耐心等待 .

    适用于iOS的LoginPageRenderer

    到目前为止,我们一直在 Xamarin.Forms PCL project 工作 . 但现在我们需要在iOS项目中提供 LoginPage 的特定于平台的实现 . 这就是 Renderer 的概念所在 .

    在Xamarin.Forms中,当您想要提供特定于平台的屏幕和控件(即不从Xamarin.Forms PCL项目中的抽象页面派生其内容的屏幕)时,您可以使用 Renderers .

    iOS platform project 中创建一个 LoginPageRenderer 类:

    [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))]
    
    namespace OAuth2Demo.XForms.iOS
    {
        public class LoginPageRenderer : PageRenderer
        {
            public override void ViewDidAppear (bool animated)
            {
                base.ViewDidAppear (animated);
    
                var auth = new OAuth2Authenticator (
                    clientId: "", // your OAuth2 client id
                    scope: "", // the scopes for the particular API you're accessing, delimited by "+" symbols
                    authorizeUrl: new Uri (""), // the auth URL for the service
                    redirectUrl: new Uri ("")); // the redirect URL for the service
    
                auth.Completed += (sender, eventArgs) => {
                // We presented the UI, so it's up to us to dimiss it on iOS.
                App.SuccessfulLoginAction.Invoke();
    
                if (eventArgs.IsAuthenticated) {
                    // Use eventArgs.Account to do wonderful things
                    App.SaveToken(eventArgs.Account.Properties["access_token"]);
                } else {
                    // The user cancelled
                }
            };
    
            PresentViewController (auth.GetUI (), true, null);
                }
            }
        }
    }
    

    有一些重要的事情需要注意:

    • 顶部的 [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] 行(重要的是 before 命名空间声明)正在使用Xamarin.Forms DependencyService . 它's not the most beautiful thing in the world because it'不是IoC / DI,但无论如何......它的工作原理 . 这是"maps"我们 LoginPageRenderer 的机制 LoginPage .

    • 这是我们're actually using the Xamarin.Auth component. That'中 OAuth2Authenticator 引用来自的类 .

    • 登录成功后,我们将通过 App.SuccessfulLoginAction.Invoke(); 启动Xamarin.Forms导航 . 这让我们回到 ProfilePage .

    • 因为我们're on iOS, we'正在做 ViewDidAppear() 方法的所有逻辑 .

    适用于Android的LoginPageRenderer

    Android platform project 中创建 LoginPageRenderer 类 . (请注意,您创建的类名与iOS项目中的类名相同,但在Android项目中,PageRenderer继承自Android类而非iOS类 . )

    [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))]
    
    namespace OAuth2Demo.XForms.Android
    {
        public class LoginPageRenderer : PageRenderer
        {
            protected override void OnModelChanged (VisualElement oldModel, VisualElement newModel)
            {
                base.OnModelChanged (oldModel, newModel);
    
                // this is a ViewGroup - so should be able to load an AXML file and FindView<>
                var activity = this.Context as Activity;
    
                var auth = new OAuth2Authenticator (
                    clientId: "", // your OAuth2 client id
                    scope: "", // the scopes for the particular API you're accessing, delimited by "+" symbols
                    authorizeUrl: new Uri (""), // the auth URL for the service
                    redirectUrl: new Uri ("")); // the redirect URL for the service
    
                auth.Completed += (sender, eventArgs) => {
                if (eventArgs.IsAuthenticated) {
                    App.SuccessfulLoginAction.Invoke();
                    // Use eventArgs.Account to do wonderful things
                    App.SaveToken(eventArgs.Account.Properties["access_token"]);
                } else {
                    // The user cancelled
                }
            };
    
            activity.StartActivity (auth.GetUI(activity));
            }
        }
    }
    

    再说一次,我们来看看一些有趣的事情:

    • 顶部的 [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] 行(重要的是 before 命名空间声明)正在使用Xamarin.Forms DependencyService . 与iOS版本的 LoginPageRenderer 没什么区别 .

    • 再一次,这就是我们're actually using the Xamarin.Auth component. That'中 OAuth2Authenticator 引用的来源 .

    • 与iOS版本一样,一旦登录成功,我们将通过 App.SuccessfulLoginAction.Invoke(); 启动Xamarin.Forms导航 . 这让我们回到 ProfilePage .

    • 与iOS版本不同,我们正在使用 OnModelChanged() 方法中的所有逻辑而不是 ViewDidAppear() .

    这是在iOS上:

    Xamarin.Auth with Xamarin.Forms iOS example

    ...和Android:

    Xamarin.Auth with Xamarin.Forms Android example

    UPDATE: 我还在我的博客上提供了详细的样本:http://www.joesauve.com/using-xamarin-auth-with-xamarin-forms/

  • 3

    @ NovaJoe的代码的另一个补充,在iOS8上使用Facebook,您需要修改Renderer类,如下所示,在成功验证后关闭View .

    auth.Completed += (sender, eventArgs) => {
                // We presented the UI, so it's up to us to dimiss it on iOS.
    

    / 导入并添加此行 /

    DismissViewController (true, null);
    

    / * * /

    if (eventArgs.IsAuthenticated) {
                    App.Instance.SuccessfulLoginAction.Invoke ();
    
                    // Use eventArgs.Account to do wonderful things
                    App.Instance.SaveToken (eventArgs.Account.Properties ["access_token"]);
    
    
                } else {
                    // The user cancelled
                }
            };
    

相关问题