22

Oct

Come fare LogIn tramite Facebook nella propria applicazione

 

Ciao a tutti

quanti di voi hanno pensato bene di usare un sistema esterno per autenticarsi alla propria applicazione?

Facebook, giusto per citare un social network a caso, ha delle potenti api per fare tutto quello che vogliamo, login, accedere a bacheca, amici, etc..

Vediamo come fare il primo passo: login nella nostra applicazione WPF tramite facebook

image

 

io ho creato una applicazione WPF con dentro un semplice usercontrol con a sua volta dentro un WebNavigator tramite un FormsHost (più lungo a dirsi che a farsi)

XAML MainWindow:

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
   
       
   


XAML UserControl:

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="600" Loaded="UserControl_Loaded">
   
       
   


nella MainWindow, noterete, c’è un semplice RoutedEvent che viene dal nostro controllo e dice all’insù (è un Bubble event – l’evento viene lanciato dal controllo all’insù nei vari contenitori fino all’Application) come è andato il processo di autenticazione:

private void FacebookLoginUserControl_AuthenticationResult(object sender, FacebookLoginUserControl.AuthenticationResultRoutedEventArgs e)
{
    if (e.IsAuthenticated)
    {
        var client = new FacebookClient(e.AuthenticationToken);
        dynamic me = client.Get("/me");
        Title = string.Format("Wellcome {0}", me.name);
    }
    else
        MessageBox.Show(e.ErrorMessage);

    (sender as FacebookLoginUserControl).Visibility = System.Windows.Visibility.Collapsed;
}

Qui abbiamo le classi della FacebookSDK di codeplex http://facebooksdk.codeplex.com/ scaricabile anche tramite NuGet comodissimo tool per scaricare altri tool Sorriso

In queste api, abbiamo li nostro client (FacebookClient) che prende in pasto un token che ci viene mandato da facebook tramite il mini-browser che abbiamo aperto e che ci permette tutta la magia che avviene in OAuth2 (protocollo di sicurezza federata)

Per far funzionare il controllo, invece, ho gestito l’evento Navigate del controllo WebBroser da cui si lancia l’evento dello UserControl:

public partial class FacebookLoginUserControl : UserControl
{
    public static readonly DependencyProperty IsAuthenticatedProperty =
        DependencyProperty.Register("IsAuthenticated", typeof(bool), typeof(FacebookLoginUserControl));

    public bool IsAuthenticated
    {
        get { return (bool)GetValue(IsAuthenticatedProperty); }
        set { SetValue(IsAuthenticatedProperty, value); }
    }

    public class AuthenticationResultRoutedEventArgs : RoutedEventArgs
    {
        public bool IsAuthenticated { get; set; }
        public string AuthenticationToken { get; set; }
        public string ErrorMessage { get; set; }
    }

    public static readonly RoutedEvent AuthenticationResultEvent = EventManager.RegisterRoutedEvent(
            "AuthenticationResult", RoutingStrategy.Bubble, typeof(AuthenticationResultEventHandler), typeof(FacebookLoginUserControl));

    public delegate void AuthenticationResultEventHandler(object sender, AuthenticationResultRoutedEventArgs e);

    public event AuthenticationResultEventHandler AuthenticationResult
    {
        add { AddHandler(AuthenticationResultEvent, value); }
        remove { RemoveHandler(AuthenticationResultEvent, value); }
    }

    public FacebookLoginUserControl()
    {
        InitializeComponent();
    }

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
    {
        string[] extendedPermissions = new[] { "publish_stream", "offline_access" };
        var oauth = new FacebookOAuthClient { AppId = General.APPID };
        var parameters = new Dictionary
        {
            { "response_type", "token" },
            { "display", "popup" }
        };

        if (extendedPermissions != null && extendedPermissions.Length > 0)
            parameters["scope"] = string.Join(",", extendedPermissions);

        var loginUrl = oauth.GetLoginUrl(parameters);

        LoginFrame.Navigate(loginUrl);
    }

    private void WebBrowser_Navigated(object sender, System.Windows.Forms.WebBrowserNavigatedEventArgs e)
    {
        FacebookOAuthResult result;
        if (FacebookOAuthResult.TryParse(e.Url, out result))
        {
            IsAuthenticated = result.IsSuccess;
            RaiseEvent(new AuthenticationResultRoutedEventArgs
            {
                RoutedEvent = AuthenticationResultEvent,
                Source = this,
                IsAuthenticated = result.IsSuccess,
                AuthenticationToken = result.AccessToken,
                ErrorMessage = string.Format("{0} ({1})", result.ErrorDescription, result.ErrorReason)
            });
        }

    }
}

 

Qui, a parte il casino per il RoutedEvent, di nostro facciamo poco: prepariamo la URL di chiamata alla pagina nascosta di facebook (quella che vediamo nel controllino WebBroser), e poi catturiamo tra i vari aggiornamenti di pagina del browserino, il momento in cui ci arriva il token, ed il gioco è fatto Sorriso

 

PS: Ovviamente per far funzionare tutto, dovete iscrivere una applicazione su developer.facebook.com, dove vi verrà data una chiave (nell’esempio è nella proprietà General.APPID) per fare la chiamata ai server di FB

a presto

by Antonio Esposito on 10/22/2011