Login Social com Facebook: Adicionando em um aplicativo já existente

Recentemente publicamos no Talkit BR um post que aborda Login Social com Facebook.

Nele temos o passo-a-passo para configurar autenticação por Facebook usando o serviço móvel do Azure. O próprio Azure fornece os projetos Android, iOS, Windows, Windows Phone, Xamarin e PhoneGap com código pronto para usar nosso serviço.

Mas muitas vezes temos um aplicativo já em desenvolvimento e queremos apenas incluir o recurso de login social. E é aqui que entra esse post, com inserções de código necessárias para incluir o login social no nosso aplicativo. Para demonstração, focaremos num aplicativo Windows Phone.

No própria página do seu serviço móvel já é disponibilizado um procedimento para incluir o serviço móvel numa aplicação já existente. O Azure também disponibiliza a página “Adicionar autenticação ao aplicativo de Serviços Móveis”.

Contudo ainda existem algumas dúvidas sobre como incluir o login social com Facebook em um aplicativo existente. Portanto, vamos detalhar aqui o passo a passo mínimo necessário para incluir o login social.

Preparando a nossa solução

Para o procedimento a seguir, vamos utilizar o projeto Universal App gerado a partir do template “HubApp” do Visual Studio:

Template "HubApp" do projeto Universal App do Visual Studio
Template “HubApp” do projeto Universal App do Visual Studio
  1. Uma vez criado o projeto, vamos incluir via nuget o pacote WindowsAzure.MobileServices que será usado para acessar o serviço móvel:
    1. Acessar o menu "TOOLS" > "NuGet Package Manager" > "Manage Nuget Packages for Solution..."
    2. Procurar pelo pacote WindowsAzure.MobileServices.
    3. Instalar o pacote nos projetos da sua solução:
      Adicionando pacote Mobile Services no nosso projeto.
      Adicionando pacote Mobile Services no nosso projeto.
    4. O Visual Studio carregará todas as referências e dependências necessárias para usar o pacote MobileServices do Azure.
  2. Agora vamos incluir o código para acessar o serviço móvel. Para tanto, abra o arquivo App.xaml.cs e inclua o código, que é disponibilizado no próprio Azure, da classe App:
    Codigo de declaração do Serviço Móvel.
    Codigo de declaração do Serviço Móvel.

    Notas:

    • Este código irá disponibilizar o serviço MobileService para ser usado na aplicação.
    • Lembrar de incluir as cláusulas using necessárias. Pode-se clicar com o botão direito do mouse na classe desconhecida e então selecionar a opção "Resolve" > "using Microsoft.WindowsAzure.MobileServices".

Adicionando código para login social

  1. O próximo passo é definirmos onde queremos restringir o acesso do usuário.
  2. No nosso exemplo aqui, vamos restringir acesso as páginas de Item de Grupo. Para tanto vamos acessar a classe HubPage.xaml.cs do projeto Windows Phone:
  3. // Define a member variable for storing the signed-in user. 
    private MobileServiceUser user;
    
    // Define a method that performs the authentication process
    // using a Facebook sign-in. 
    private async System.Threading.Tasks.Task AuthenticateAsync()
    {
        while (user == null)
        {
            string message;
            try
            {
                // Change 'MobileService' to the name of your MobileServiceClient instance.
                // Sign-in using Facebook authentication.
                user = await App.MobileService
                    .LoginAsync(MobileServiceAuthenticationProvider.Facebook);
                message = 
                    string.Format("You are now signed in - {0}", user.UserId);
            }
            catch (InvalidOperationException)
            {
                message = "You must log in. Login Required";
            }
    
            var dialog = new MessageDialog(message);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
        }
    }
         

    Notas:

  4. Agora podemos tanto incluir botão (ou AppBarButton) para login na página como também disparar a janela de login quando o usuário tentar fazer algum procedimento que necessita de autenticação. Por exemplo, vamos incluir o seguinte AppBarButton para login. Vamos adicionar o código em HubPage.xaml:
    <Page.BottomAppBar>
        <CommandBar>
            <AppBarButton x:Name="Login" Icon="Permissions" Label="login" Click="Login_Click"/>
        </CommandBar>
    </Page.BottomAppBar>
          
  5. E depois no HubPage.xaml.cs o seguinte código:
    private async void Login_Click(object sender, RoutedEventArgs e)
    {
        // Login the user using the mobile service.
        await AuthenticateAsync();
    }
         

    Nota: Esse código está requisitando diretamente autenticação através do método AuthenticateAsync.

  6. Já para restringir acesso a uma parte específica do código, basta também incluirmos uma chamada para o método AuthenticateAsync. Por exemplo, vamos alterar nosso código em HubPage.xaml.cs para invocar o método de autenticação ao clicar num item ou num grupo:
    /// <summary>
    /// Shows the details of a clicked group in the <see cref="SectionPage"/>.
    /// </summary>
    /// <param name="sender">The source of the click event.</param>
    /// <param name="e">Details about the click event.</param>
    private async void GroupSection_ItemClick(object sender, ItemClickEventArgs e)
    {
        // Login the user using the mobile service.
        await AuthenticateAsync();
    
        var groupId = ((SampleDataGroup)e.ClickedItem).UniqueId;
        if (!Frame.Navigate(typeof(SectionPage), groupId))
        {
            throw new Exception(this.resourceLoader.GetString("NavigationFailedExceptionMessage"));
        }
    }
     
    /// <summary>
    /// Shows the details of an item clicked on in the <see cref="ItemPage"/>
    /// </summary>
    /// <param name="sender">The source of the click event.</param>
    /// <param name="e">Defaults about the click event.</param>
    private async void ItemView_ItemClick(object sender, ItemClickEventArgs e)
    {
        // Login the user using the mobile service.
        await AuthenticateAsync();
        
        var itemId = ((SampleDataItem)e.ClickedItem).UniqueId;
        if (!Frame.Navigate(typeof(ItemPage), itemId))
        {
            throw new Exception(this.resourceLoader.GetString("NavigationFailedExceptionMessage"));
        }
    }
         

    Nota: Lembrar de incluir a palavra chave async na declaração dos métodos listados acima.

  7. Para finalizar, precisamos incluir na classe App.xaml.cs o código que será executado quando nosso aplicação for ativada novamente. Isso é necessário somente para Windows Phone porque quando abrimos a tela de autenticação, a nossa aplicação é suspensa. E quando concluímos a autenticação, a nossa aplicação retorna.
    protected override void OnActivated(IActivatedEventArgs args)
    {
        // Windows Phone 8.1 requires you to handle the respose from the WebAuthenticationBroker.
    #if WINDOWS_PHONE_APP
    if (args.Kind == ActivationKind.WebAuthenticationBrokerContinuation)
    {
    // Completes the sign-in process started by LoginAsync.
    // Change 'MobileService' to the name of your MobileServiceClient instance. 
    App.MobileService.LoginComplete(args as WebAuthenticationBrokerContinuationEventArgs);
    }
    #endif
     
        base.OnActivated(args);
    }
         

    Notas:

    • Caso já tenha definido o método OnActivated no seu App.xaml.cs, basta incluir bloco de código #if...#endif.
    • No caso do projeto “Windows”, esse procedimento não é necessário.
  8. Pronto! Vamos testar nossa aplicação?
  9. Ao clicar no AppBarButton de autenticação ou ao tentar acessar um item/grupo, nosso aplicativo é suspenso e então é aberta a janela de autenticação do facebook:
    Mostrando tela de login no facebook.
    Mostrando tela de login no facebook.
  10. Depois da autenticação, obtemos o id do facebook do usuário autenticado.
    Resultado após login bem sucedido no Facebook.
    Resultado após login bem sucedido no Facebook.

Armazenando Credencial do Usuário na nossa Aplicação

  1. O procedimento foi baseado no artigo em “Adicionar autenticação ao aplicativo de Serviços Móveis”
  2. Do jeito que fizemos até agora, toda vez que o aplicativo for iniciado, ele solicitará autenticação para o usuário.
  3. Podemos aperfeiçoar o código de modo que uma vez autenticado, o usuário não precise novamnete fornecer suas credenciais nesse aplicativo.
  4. Camos começar baixando o código do nosso serviço. Para tanto, acesse a página do ser serviço móvel no Azure e selecione a opção “CONECTAR A UM APLICATIVO WINDOWS OU WINDOWS PHONE EXISTENTE”:
    Baixando código do Serviço Móvel
    Baixando código do Serviço Móvel

  5. Para tanto, vamos substituir o método AuthenticateAsync() que incluímos na classe HubPage.xaml.cs:
  6. private async System.Threading.Tasks.Task AuthenticateAsync()
    {
        string message;
        // This sample uses the Facebook provider.
        var provider = "Facebook";
     
        // Use the PasswordVault to securely store and access credentials.
        PasswordVault vault = new PasswordVault();
        PasswordCredential credential = null;
     
        while (credential == null)
        {
            try
            {
                // Try to get an existing credential from the vault.
                credential = vault.FindAllByResource(provider).FirstOrDefault();
            }
            catch (Exception)
            {
                // When there is no matching resource an error occurs, which we ignore.
            }
     
            if (credential != null)
            {
                // Create a user from the stored credentials.
                user = new MobileServiceUser(credential.UserName);
                credential.RetrievePassword();
                user.MobileServiceAuthenticationToken = credential.Password;
     
                // Set the user from the stored credentials.
                App.MobileService.CurrentUser = user;
     
                try
                {
                    // Try to return an item now to determine if the cached credential has expired.
                    await App.MobileService.GetTable<TodoItem>().Take(1).ToListAsync();
                }
                catch (MobileServiceInvalidOperationException ex)
                {
                    if (ex.Response.StatusCode == System.Net.HttpStatusCode.Unauthorized)
                    {
                        // Remove the credential with the expired token.
                        vault.Remove(credential);
                        credential = null;
                        continue;
                    }
                }
            }
            else
            {
                try
                {
                    // Login with the identity provider.
                    user = await App.MobileService
                        .LoginAsync(provider);
     
                    // Create and store the user credentials.
                    credential = new PasswordCredential(provider,
                        user.UserId, user.MobileServiceAuthenticationToken);
                    vault.Add(credential);
                }
                catch (MobileServiceInvalidOperationException ex)
                {
                    message = "You must log in. Login Required";
                }
            }
            message = string.Format("You are now logged in - {0}", user.UserId);
            var dialog = new MessageDialog(message);
            dialog.Commands.Add(new UICommand("OK"));
            await dialog.ShowAsync();
        }
    }
        

    Notas:

    • Lembrar de incluir as clausulas using necessárias.
    • Incluímos o PasswordVault e PasswordVaultCredential para armazenar a credencial do usuário.
    • Ele tenta usar a credencial armazenada no PasswordVault, caso exista e ainda não tenha expirado. Se falhar, ele solicita novamente a credencial para o usuário.
    • O código acima verifica se a credencial está expirada somente no login. Para verificar se a credencial expirou após o login e durante o uso do aplicativo, será necessário adotar outra solução conforme descrito em Armazenagem em cache e manipulação de tokens expirados no SDK gerenciado pelos Serviços Móveis do Azure.

Considerações Finais

Ficou evidente a partir do código aqui exposto, que a inclusão de login social é relativamente simples quando usamos o Azure. Demonstramos o login usando Facebook mas poderíamos ter usado também Twitter, Google, conta Microsoft ou Azure Active Directory, sendo que todos eles são configurados no mesmo serviço móvel:

Referências

Para este post, usamos como base a documentação do Azure Adicionar autenticação ao seu aplicativo de Serviços Móveis.

Continue acompanhando o #talkitbr para novos tutoriais e novidades!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s