xamarin xamarin.forms

Cómo iniciar sesión en facebook en Xamarin.Forms



(6)

Aquí hay una buena muestra de autenticación de Xamarin.Forms. La documentación en el código es agradable. Utiliza una vista web para mostrar la pantalla de inicio de sesión, pero puede seleccionar qué tipo de inicio de sesión desea. También guarda un token de usuarios para que no tenga que volver a iniciar sesión.

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

Quiero hacer un proyecto Xamarin.Forms, apuntando a iOs, Android y Windows Phone.

Mi aplicación necesita autenticar usuarios, usando Facebook.

¿Debo implementar el inicio de sesión para cada plataforma de forma independiente o utilizar un flujo manual? https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0

Prefiero tener una implementación única del flujo de inicio de sesión y usarlo en todas las plataformas.

¿Cómo puedo obtener una implementación única del flujo de inicio de sesión de Facebook?


Creé un proyecto de muestra para mostrar cómo crear un inicio de sesión de Facebook usando un componente nativo de Facebook, no a través de una vista web como las soluciones sugeridas aquí. Puede verificarlo en esta dirección:

https://github.com/IdoTene/XamarinFormsNativeFacebook


Otra adición al código de @ NovaJoe, en iOS8 con Facebook, necesitaría modificar la clase Renderer de la siguiente manera para cerrar la vista después de la autenticación exitosa.

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

/ * Importand para agregar esta línea * /

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


Podrías consumir Xamarin.Social o Xamarin.Auth por eso. Permite usar la misma API independientemente de la plataforma.

A partir de ahora, esas libs aún no son PCL, pero aún puede consumirlas desde un Proyecto de Activos Compartidos, o abstraer la API que necesita en una interfaz e inyectar con DependencyService o cualquier otro contenedor DI.


ACTUALIZACIÓN (10/24/17): Si bien esta forma de hacer las cosas estuvo bien hace unos años, ahora abogo firmemente por usar la interfaz de usuario nativa para hacer la autenticación, a diferencia del método de vista web que se muestra aquí. Auth0 es una forma excelente de realizar el inicio de sesión UI nativo para sus aplicaciones, usando una amplia variedad de proveedores de identidad: https://auth0.com/docs/quickstart/native/xamarin

EDIT: finalmente puse una muestra para esto en Gihub

Publiqué una respuesta en los foros de Xamarin. Lo repetiré aquí.

Comencemos con el núcleo de la aplicación, el proyecto PCL Xamarin.Forms . Tu clase de App se verá más o menos así:

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

Lo primero que debe observar es el método GetMainPage() . Esto le dice a la aplicación qué pantalla debe cargar primero al momento del lanzamiento.

También tenemos una propiedad y método simples para almacenar el Token que se devuelve desde el servicio de autenticación, así como una propiedad IsLoggedIn simple.

También hay una propiedad de Acción; algo que atrapé aquí para tener una forma de que las implementaciones de la plataforma realicen una acción de navegación Xamarin.Forms. Más sobre esto más tarde.

También notará algo de rojo en su IDE porque aún no hemos creado la clase ProfilePage . Entonces, hagamos eso.

Cree una clase ProfilePage muy simple en el proyecto PCL Xamarin.Forms . Ni siquiera vamos a hacer nada elegante con eso porque eso dependerá de su necesidad particular. En aras de la simplicidad en esta muestra, contendrá una sola etiqueta:

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

Nuevamente, probablemente tenga algo de rojo en su IDE porque parece que nos falta la clase BaseContentPage . El único propósito de la clase BaseContentPage es garantizar que ninguna de las pantallas de la aplicación se pueda mostrar hasta que el usuario haya iniciado sesión. (En esta demostración simplificada, simplemente estamos conservando la información del usuario en la memoria, por lo que deberá volver a -login cada vez que se ejecuta la aplicación. En una aplicación del mundo real, estaría almacenando la información del usuario autenticado en el llavero del dispositivo, lo que eliminaría la necesidad de iniciar sesión en cada inicio de la aplicación).

Cree una clase BaseContentPage en el proyecto PCL Xamarin.Forms :

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

Hay algunas cosas interesantes que están pasando aquí:

  1. Estamos anulando el método OnAppearing() , que es similar al método ViewWillAppear en un UIViewController de iOS. Puede ejecutar cualquier código aquí que desee ejecutar inmediatamente antes de que aparezca la pantalla.

  2. Lo único que estamos haciendo en este método es verificar si el usuario está conectado. Si no lo están, entonces realizamos un impulso modal a una clase llamada LoginPage . Si no está familiarizado con el concepto de modal, es simplemente una vista que saca al usuario del flujo normal de la aplicación para realizar alguna tarea especial; en nuestro caso, para realizar un inicio de sesión.

Entonces, LoginPage clase LoginPage en el proyecto PCL Xamarin.Forms :

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

Espera ... ¿por qué esta clase no tiene cuerpo?

Como usamos el componente Xamatin.Auth (que hace el trabajo de compilar y presentar una vista web que funciona con la información OAuth2 proporcionada), en realidad no queremos ningún tipo de implementación en nuestra clase LoginPage . Sé que parece extraño, pero tengan paciencia conmigo.

El LoginPageRenderer para iOS

Hasta este momento, hemos estado trabajando exclusivamente en el proyecto PCL Xamarin.Forms . Pero ahora necesitamos proporcionar la implementación específica de la plataforma de nuestra página de LoginPage de LoginPage en el proyecto de iOS. Aquí es donde entra el concepto de un Renderer

En Xamarin.Forms, cuando desea proporcionar pantallas y controles específicos de la plataforma (es decir, pantallas que no derivan su contenido de las páginas abstractas en el proyecto PCL Xamarin.Forms), lo hace con Renderers .

Cree una clase LoginPageRenderer en su proyecto de plataforma iOS :

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

Hay cosas importantes a tener en cuenta:

  1. La línea [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] en la parte superior (y lo que es más importante antes de la declaración del espacio de nombres) está utilizando Xamarin.Forms DependencyService . No es lo más hermoso del mundo porque no es IoC / DI, pero lo que sea ... funciona. Este es el mecanismo que "mapea" nuestro LoginPageRenderer a la LoginPage LoginPageRenderer de LoginPage .

  2. Esta es la clase en la que estamos usando el componente Xamarin.Auth. De OAuth2Authenticator viene la referencia de OAuth2Authenticator .

  3. Una vez que el inicio de sesión es exitoso, activamos una navegación de App.SuccessfulLoginAction.Invoke(); través de App.SuccessfulLoginAction.Invoke(); . Esto nos lleva de vuelta a ProfilePage .

  4. Como estamos en iOS, estamos haciendo toda nuestra lógica del método ViewDidAppear() .

El LoginPageRenderer para Android

Cree una clase LoginPageRenderer en su proyecto de plataforma Android . (Tenga en cuenta que el nombre de clase que está creando es idéntico al del proyecto de iOS, pero aquí, en el proyecto de Android, PageRenderer hereda de las clases de Android en lugar de las clases de 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)); } } }

Nuevamente, echemos un vistazo a algunas cosas interesantes:

  1. La línea [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] en la parte superior (y lo que es más importante antes de la declaración del espacio de nombres) está utilizando Xamarin.Forms DependencyService . No hay diferencia aquí desde la versión de iOS de LoginPageRenderer .

  2. Nuevamente, aquí es donde estamos usando el componente Xamarin.Auth. De OAuth2Authenticator viene la referencia de OAuth2Authenticator .

  3. Al igual que con la versión de iOS, una vez que el inicio de sesión es exitoso, activamos una navegación con App.SuccessfulLoginAction.Invoke(); través de App.SuccessfulLoginAction.Invoke(); . Esto nos lleva de vuelta a ProfilePage .

  4. A diferencia de la versión de iOS, estamos haciendo toda la lógica dentro del método OnModelChanged() lugar de ViewDidAppear() .

Aquí está en iOS:

... y Android:

ACTUALIZACIÓN: también proporcioné una muestra detallada en mi blog: http://www.joesauve.com/using-xamarin-auth-with-xamarin-forms/


IOS 8: para aquellos que están utilizando el código @NovaJoe y están atascados en la vista, agregue el siguiente código para la solución alternativa:

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