Como fazer login no facebook em Xamarin.Forms

Eu quero fazer um projeto Xamarin.Forms, visando iOs, Android e Windows Phone.

Meu aplicativo precisa autenticar usuários usando o Facebook.

Devo implementar o login para cada plataforma de forma independente ou usar um stream manual? https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow/v2.0

Eu prefiro ter uma única implementação do stream de login e usá-lo em todas as plataformas.

Como posso obter uma única implementação do stream de login do facebook?

Você pode consumir Xamarin.Social ou Xamarin.Auth para isso. Ele permite usar a mesma API, seja qual for a plataforma.

A partir de agora, essas libs ainda não são PCL, mas você ainda pode consumi-las a partir de um Projeto de Ativos Compartilhados, ou abstrair a API que você precisa em uma interface e injetar com DependencyService ou qualquer outro contêiner DI.

ATUALIZAÇÃO (24/10/17): Embora essa maneira de fazer as coisas estivessem bem há alguns anos, agora defendo fortemente o uso da interface do usuário nativa para fazer autenticação, ao contrário do método de visualização da Web mostrado aqui. O Auth0 é uma ótima maneira de realizar login de interface do usuário nativo para seus aplicativos, usando uma grande variedade de provedores de identidade: https://auth0.com/docs/quickstart/native/xamarin

EDIT: Eu finalmente coloquei uma amostra para isso em Gihub

Eu postei uma resposta nos fóruns de Xamarin. Eu vou repetir aqui.

Vamos começar com o núcleo do aplicativo, o projeto Xamarin.Forms PCL . Sua class App será algo parecido com isto:

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

A primeira coisa a notar é o método GetMainPage() . Isso informa ao aplicativo qual canvas deve ser carregada primeiro ao ser iniciado.

Também temos uma propriedade e um método simples para armazenar o Token retornado do serviço de autenticação, bem como uma propriedade IsLoggedIn simples.

Há uma propriedade Action também; algo que eu coloquei aqui para ter um jeito de as implementações de plataforma executarem uma ação de navegação Xamarin.Forms. Mais sobre isso depois.

Você também notará um pouco de vermelho no seu IDE porque ainda não criamos a class ProfilePage . Então, vamos fazer isso.

Crie uma class ProfilePage muito simples no projeto PCL Xamarin.Forms . Nós nem vamos fazer nada extravagante com isso, porque isso dependerá de sua necessidade particular. Por uma questão de simplicidade neste exemplo, ele conterá um único label:

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

Novamente, você provavelmente terá algum vermelho em seu IDE porque parece que está faltando a class BaseContentPage . O único propósito da class BaseContentPage é garantir que nenhuma das canvass do aplicativo possa ser exibida até que o usuário tenha BaseContentPage login. (Nesta demonstração simplificada, estamos apenas persistindo as informações do usuário na memory, então você precisará -login toda vez que o aplicativo é executado. Em um aplicativo do mundo real, você estaria armazenando as informações do usuário autenticado no keychain do dispositivo, o que eliminaria a necessidade de fazer login no início de cada aplicativo.

Crie uma class BaseContentPage no projeto PCL Xamarin.Forms :

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

Há algumas coisas interessantes acontecendo aqui:

  1. Estamos substituindo o método OnAppearing() , que é semelhante ao método ViewWillAppear em um UIViewController do iOS. Você pode executar qualquer código aqui que gostaria de executar imediatamente antes da canvas aparecer.

  2. A única coisa que estamos fazendo nesse método é verificar se o usuário está logado. Se não estiverem, então executamos um push modal para uma class chamada LoginPage . Se você não estiver familiarizado com o conceito de um modal, é simplesmente uma exibição que tira o usuário do stream normal do aplicativo para executar alguma tarefa especial; no nosso caso, para realizar um login.

Então, vamos criar a class LoginPage no projeto PCL Xamarin.Forms :

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

Espere … por que essa class não tem um corpo ???

Como estamos usando o componente Xamatin.Auth (que faz o trabalho de criar e apresentar uma visualização da Web que funciona com as informações do OAuth2 fornecidas), na verdade, não queremos nenhum tipo de implementação em nossa class LoginPage . Eu sei que parece estranho, mas tenha paciência comigo.

O LoginPageRenderer para iOS

Até este ponto, estamos trabalhando exclusivamente no projeto Xamarin.Forms PCL . Mas agora precisamos fornecer a implementação específica da plataforma do nosso LoginPage no projeto iOS. É aí que entra o conceito de renderizador .

Em Xamarin.Forms, quando você deseja fornecer canvass e controles específicos da plataforma (ou seja, canvass que não derivam seu conteúdo das páginas abstratas do projeto PCL Xamarin.Forms), você faz isso com Renderers .

Crie uma class LoginPageRenderer no seu projeto 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); } } } } 

Há coisas importantes a serem observadas:

  1. A linha [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] na parte superior (e importante antes da declaração de namespace) está usando o Xamarin.Forms DependencyService . Não é a coisa mais bonita do mundo porque não é IoC / DI, mas seja o que for … funciona. Este é o mecanismo que “mapeia” nosso LoginPageRenderer para o LoginPage .

  2. Esta é a class na qual estamos realmente usando o componente Xamarin.Auth. É OAuth2Authenticator que vem a referência do OAuth2Authenticator .

  3. Uma vez que o login é bem sucedido, nós triggersmos uma navegação App.SuccessfulLoginAction.Invoke(); via App.SuccessfulLoginAction.Invoke(); . Isso nos leva de volta ao ProfilePage .

  4. Já que estamos no iOS, estamos fazendo toda a nossa lógica do método ViewDidAppear() .

O LoginPageRenderer para Android

Crie uma class LoginPageRenderer no seu projeto de plataforma Android . (Observe que o nome da class que você está criando é idêntico ao do projeto iOS, mas aqui no projeto Android, o PageRenderer herda de classs Android em vez de classs 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)); } } } 

Mais uma vez, vamos dar uma olhada em algumas coisas interessantes:

  1. A linha [assembly: ExportRenderer (typeof (LoginPage), typeof (LoginPageRenderer))] na parte superior (e importante antes da declaração de namespace) está usando o Xamarin.Forms DependencyService . Nenhuma diferença aqui da versão iOS do LoginPageRenderer .

  2. Novamente, é aqui que estamos realmente usando o componente Xamarin.Auth. É OAuth2Authenticator que vem a referência do OAuth2Authenticator .

  3. Assim como na versão para iOS, quando o login é bem-sucedido, triggersmos uma navegação App.SuccessfulLoginAction.Invoke(); via App.SuccessfulLoginAction.Invoke(); . Isso nos leva de volta ao ProfilePage .

  4. Ao contrário da versão do iOS, estamos fazendo toda a lógica dentro do método OnModelChanged() vez do ViewDidAppear() .

Aqui está no iOS:

Xamarin.Auth com Xamarin.Forms iOS exemplo

… e Android:

Xamarin.Auth com Xamarin.Forms exemplo Android

ATUALIZAÇÃO: Eu também forneci uma amostra detalhada no meu blog: http://www.joesauve.com/using-xamarin-auth-with-xamarin-forms/

Eu criei um projeto de exemplo para mostrar como criar um login no Facebook usando o componente nativo do Facebook, não por meio de uma visualização da Web como as soluções sugeridas aqui. Você pode verificá-lo neste endereço:

https://github.com/IdoTene/XamarinFormsNativeFacebook

IOS 8: Para aqueles que estão usando o código @NovaJoe e estão presos na visualização, adicione o código abaixo à solução alternativa:

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

Aqui está uma boa amostra de autenticação Xamarin.Forms. A documentação no código é legal. Ele usa uma visualização da Web para renderizar a canvas de login, mas você pode selecionar o tipo de login desejado. Ele também salva um token de usuário para que ele não tenha que fazer o login novamente.

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

Outra adição ao código da @ NovaJoe, no iOS8 com o Facebook, você precisaria modificar a class Renderer como abaixo para fechar a View após a autenticação bem-sucedida.

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

/ * Importando para adicionar esta linha * /

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