Jak zalogować się na Facebook w Xamarin.Formularze

Chcę zrobić Xamarin.Projekt formularzy, kierowanie na iOS, Android i Windows Phone.

Moja aplikacja musi uwierzytelniać użytkowników za pomocą Facebook.

Czy powinienem zaimplementować Logowanie dla każdej platformy niezależnie, czy skorzystać z ręcznego przepływu? https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0

Wolę mieć jedną implementację przepływu logowania i używać go na wszystkich platformach.

How can I get a single implementacja Facebook login flow?

Author: Boann, 2014-06-08

7 answers

Xamarin.Social lub Xamarin.Auth za to. Pozwala na korzystanie z tego samego api niezależnie od platformy.

Jak na razie te biblioteki nie są jeszcze PCL, ale nadal można je wykorzystać z projektu zasobów współdzielonych lub abstrakcji API, którego potrzebujesz w interfejsie i wstrzyknąć za pomocą DependencyService lub innego kontenera DI.

 20
Author: Stephane Delcroix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-08 11:07:52

UPDATE (10/24/17): chociaż ten sposób działania był w porządku kilka lat temu, teraz zdecydowanie opowiadam się za używaniem natywnego interfejsu użytkownika do uwierzytelniania, w przeciwieństwie do metody webview pokazanej tutaj. Auth0 to świetny sposób, aby uzyskać natywne logowanie UI dla aplikacji, przy użyciu różnych dostawców tożsamości: https://auth0.com/docs/quickstart/native/xamarin

EDIT: W końcu umieściłem próbkę do tego na Gihub

I posted an answer Na forach Xamarin.Powtórzę to tutaj.

Zacznijmy od rdzenia aplikacji, Xamarin.Forms PCL project . Twoja App klasa będzie wyglądać mniej więcej tak:

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();
                });
            }
        }
    }
}

Pierwszą rzeczą, na którą należy zwrócić uwagę, jest metoda GetMainPage(). To mówi aplikacji, który ekran powinien załadować się najpierw po uruchomieniu.

Mamy również prostą właściwość i metodę do przechowywania Token, która jest zwracana z usługi auth, a także prostą IsLoggedIn własność.

Jest też właściwość Action; coś, co utknąłem tutaj, aby mieć sposób na implementacje platformy do wykonywania Xamarin.Forms navigation action. Więcej na ten temat później.

Zauważysz też trochę czerwieni w IDE, ponieważ nie stworzyliśmy jeszcze klasy ProfilePage. Zróbmy to.

Utwórz bardzo prostą klasę ProfilePage W Xamarin.Forms PCL project . Nawet nie zrobimy z tym nic wymyślnego, bo to będzie zależeć od twoja szczególna potrzeba. Ze względu na prostotę w tej próbce, będzie ona zawierała jedną etykietę:

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

Ponownie, prawdopodobnie będziesz miał trochę czerwonego w IDE, ponieważ wydaje się, że brakuje BaseContentPage klasy. Jedynym celem klasy BaseContentPage jest zapewnienie, że żaden z ekranów aplikacji nie może być wyświetlany, dopóki użytkownik nie zaloguje się. (w tej uproszczonej wersji demonstracyjnej po prostu przechowujemy informacje o użytkowniku w pamięci, więc musisz ponownie zalogować się za każdym razem, gdy aplikacja jest uruchomiona. W realnej aplikacji, uwierzytelnione informacje o użytkowniku będą przechowywane w pęku kluczy urządzenia, co wyeliminuje konieczność logowania się przy każdym uruchomieniu aplikacji.)

Utwórz klasę BaseContentPage W Xamarin.Formularze PCL project :

namespace OAuth2Demo.XForms
{
    public class BaseContentPage : ContentPage
    {
        protected override void OnAppearing ()
        {
            base.OnAppearing ();

            if (!App.IsLoggedIn) {
                Navigation.PushModalAsync(new LoginPage());
            }
        }
    }
}

Dzieje się tu kilka ciekawych rzeczy:

  1. Nadpisujemy metodę OnAppearing(), która jest podobna do metody Viewwillappear w kontrolerze iOS UIViewController. Możesz wykonać dowolny kod, który chcesz uruchomić bezpośrednio przed pojawi się ekran.

  2. Jedyną rzeczą, którą robimy w tej metodzie, jest sprawdzenie, czy użytkownik jest zalogowany. Jeśli nie, to wykonujemy modal push do klasy o nazwie LoginPage. Jeśli nie znasz pojęcia modalnego, jest to po prostu widok, który zabiera użytkownika z normalnego przepływu aplikacji w celu wykonania jakiegoś specjalnego zadania; w naszym przypadku, aby wykonać logowanie.

Więc stwórzmy LoginPage klasę w Xamarin.Formularze Projekt PCL :

namespace OAuth2Demo.XForms
{
    public class LoginPage : ContentPage
    {

    }
}
Czekaj...dlaczego ta klasa nie ma ciała???

Odkąd używamy Xamatinu.Komponent Auth (który wykonuje zadanie budowania i prezentowania widoku sieci Web, który działa z dostarczonymi informacjami OAuth2), w rzeczywistości nie chcemy żadnej implementacji w naszej klasie LoginPage. Wiem, że to dziwne, ale proszę mi wybaczyć.

[[98]}LoginPageRenderer dla iOS [99]} Do tej pory pracowaliśmy wyłącznie w Xamarin.Formularze PCL projekt . Ale teraz musimy zapewnić implementację naszej platformy LoginPage w projekcie iOS. W tym miejscu pojawia się koncepcja renderera .

W Xamarin.Formularze, jeśli chcesz udostępnić ekrany i kontrolki specyficzne dla platformy (tzn. ekrany, które nie czerpią swojej zawartości ze stron abstrakcyjnych w Xamarin.Forms PCL project), robisz to za pomocą Rendererów.

Utwórz klasę LoginPageRenderer na swojej platformie iOS projekt:

[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);
            }
        }
    }
}

Są ważne rzeczy do odnotowania:

  1. Linia [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] na górze (i co ważne przed deklaracją przestrzeni nazw) używa Xamarin.Formularze DependencyService . Nie jest to najpiękniejsza rzecz na świecie, bo nie jest to najpiękniejsza rzecz na świecie, ale whatever...it działa. Jest to mechanizm, który "mapuje" nasze LoginPageRenderer na LoginPage.

  2. To jest klasa, w której używamy Xamarin.Auth komponent. Stąd pochodzi odniesienie OAuth2Authenticator.

  3. Po pomyślnym zalogowaniu uruchamiamy Xamarin.Forms navigation via App.SuccessfulLoginAction.Invoke();. To prowadzi nas z powrotem do ProfilePage.

  4. Ponieważ jesteśmy na iOS, wykonujemy całą naszą logikę sinde metody ViewDidAppear().

[[98]}LoginPageRenderer dla Androida [99]}

Utwórz klasę LoginPageRenderer w swoim projekcie platformy Android}. (zauważ, że nazwa klasy, którą tworzysz, jest identyczna do tego w projekcie iOS, ale tutaj w projekcie Android PageRenderer dziedziczy z klas Androida zamiast klas 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));
        }
    }
}

Jeszcze raz, rzućmy okiem na kilka ciekawych rzeczy:

  1. Linia [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] na górze (i co ważne przed deklaracją przestrzeni nazw) używa Xamarin.Formularze DependencyService . Nie ma tu żadnej różnicy od wersji na iOS LoginPageRenderer.

  2. Znowu tu jesteśmy używam Xamarinu.Komponent Auth. Stąd pochodzi odniesienie OAuth2Authenticator.

  3. Podobnie jak w wersji na iOS, po pomyślnym zalogowaniu odpalamy Xamarina.Forms navigation via App.SuccessfulLoginAction.Invoke();. To prowadzi nas z powrotem do ProfilePage.

  4. W przeciwieństwie do wersji iOS, wykonujemy całą logikę wewnątrz metody OnModelChanged() zamiast ViewDidAppear().

To jest na iOS:]}

Xamarin.Auth z Xamarin.Formularze iOS przykład

...oraz Android:

Xamarin.Auth z Xamarin.Formularze Android przykład

Aktualizacja: Podałem również szczegółową próbkę na moim blogu: http://www.joesauve.com/using-xamarin-auth-with-xamarin-forms/

 105
Author: NovaJoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Facebook facebook to narzędzie do tworzenia loginu na Facebooku za pomocą natywnego komponentu Facebooka, a nie poprzez webview, jak sugerowane tutaj rozwiązania...........:):):):):):):):):):):):):):) Możesz to sprawdzić pod tym adresem:

Https://github.com/IdoTene/XamarinFormsNativeFacebook

 9
Author: IdoT,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-12 11:58:54

IOS 8: dla tych, którzy używają kodu @ NovaJoe i utknęli w widoku, dodaj poniższy kod do obejścia:

 bool hasShown;

    public override void ViewDidAppear(bool animated)
    {
        if (!hasShown)
        {
            hasShown = true;

            // the rest of @novaJoe code
        }

    }
 5
Author: Alexandre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-15 17:54:01

Oto dobry Xamarin.Próbka uwierzytelniania formularzy. Dokumentacja w kodzie jest ładna. Używa widoku sieci Web do renderowania ekranu logowania, ale możesz wybrać, jaki typ logowania chcesz. Zapisuje również token użytkownika, aby nie musiał ponownie logować się.

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

 3
Author: MangoBoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-21 04:04:16

Kolejny dodatek do kodu @ NovaJoe, na iOS8 z Facebook, musisz zmodyfikować klasę renderera jak poniżej, aby zamknąć widok po udanym uwierzytelnieniu.

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

/*ważne aby dodać ten wiersz * /

            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
            }
        };
 0
Author: Illuminati,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-26 05:21:04

Prawidłowa implementacja Pagerendera androidów to:

using System;
using Android.App;
using Android.Content;
using OAuth2Demo.XForms.Android;
using Xamarin.Auth;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using XamarinAuth;

[assembly: ExportRenderer(typeof(LoginPage), typeof(LoginPageRenderer))]

namespace OAuth2Demo.XForms.Android
{
    public class LoginPageRenderer : PageRenderer
    {
        public LoginPageRenderer(Context context) : base(context) { }

        protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
        {
            base.OnElementChanged(e);

            // 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: "<Constants.clientId>", // your OAuth2 client id
                scope: "<Constants.scope>", // the scopes for the particular API you're accessing, delimited by "+" symbols
                authorizeUrl: new Uri("<Constants.authorizeUrl>"), // the auth URL for the service
                redirectUrl: new Uri("<Constants.redirectUrl>")); // 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));
        }
    }
}
 0
Author: Janis Thr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-04-15 14:27:55