Facebook OAuth w WPF i C # Przykład [zamknięte]

Zajmuję się tworzeniem aplikacji WPF, która wymaga od mnie uzyskania tokenu dostępuFacebook używający oAuth. Po wielu poszukiwaniach w Internecie doszedłem do następujących wniosków:

OAuth musi być wykonane w przeglądarceMuszę oglądać posty URL w tej przeglądarce, dlatego musi być wewnątrzPrzeglądarka internetowa Kontrola WPF

Postanowiłem stworzyć Modalne okno dialogowe do autoryzacji Facebooka i mogę po prostu wziąć token dostępu i zignorować resztę. Chciałem trzymać się modelu MVVM, ale było to trudniejsze niż się spodziewałem.Wszelkie pomysły, jak to zrobić, byłyby bardzo pomocne

Oto kilka funkcji, które zaimplementowałem

Usuwanie plików cookie więc może zostać uwierzytelniony inny użytkownik bez konieczności logowania bieżącego użytkownikaWyłącz tworzenie nowego konta ponieważ doprowadziło to do dziwnego doświadczenia z interfejsem użytkownikaSłuchanie przycisku anulowania z javascript generowanego przez FacebookaOkno WPF

WPF jest bardzo prosty. W istocie jest to tylko formant WebBrowser z połączonymi zdarzeniami Navigated i Navigating.

<Window x:Class="FacebookAuthenticator.FacebookAuthenticationWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Authenticate Facebook" 
        Height="600" 
        Width="600" 
        ResizeMode="NoResize" 
        WindowStyle="ToolWindow">
<Grid>
    <WebBrowser Name="webBrowser" 
                Navigated="webBrowser_Navigated" 
                Navigating="webBrowser_Navigating" />
</Grid>

Kod
//The Application ID from Facebook
public string AppID {get; set; }

//The access token retrieved from facebook's authentication
public string AccessToken {get; set; }

public FacebookAuthenticationWindow()
{
    InitializeComponent();
    this.Loaded += (object sender, RoutedEventArgs e) =>
    {
        //Add the message hook in the code behind since I got a weird bug when trying to do it in the XAML
        webBrowser.MessageHook += webBrowser_MessageHook;

        //Delete the cookies since the last authentication
        DeleteFacebookCookie();

        //Create the destination URL
        var destinationURL = String.Format("https://www.facebook.com/dialog/oauth?client_id={0}&scope={1}&display=popup&redirect_uri=http://www.facebook.com/connect/login_success.html&response_type=token",
           AppID, //client_id
           "email,user_birthday" //scope
        );
        webBrowser.Navigate(destinationURL);
    };
}
Uzyskiwanie tokena dostępu

Zapomniałem dokładnie, skąd mam ten kod (jeśli ktoś może mi przypomnieć, żebym mógł udzielić właściwego kredytu, byłbym wdzięczny).

private void webBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
    //If the URL has an access_token, grab it and walk away...
    var url = e.Uri.Fragment;
    if (url.Contains("access_token") && url.Contains("#"))
    {
        url = (new System.Text.RegularExpressions.Regex("#")).Replace(url, "?", 1);
        AccessToken = System.Web.HttpUtility.ParseQueryString(url).Get("access_token");
        DialogResult = true;
        this.Close();
    }
}
Usuwanie plików cookie

Zdałem sobie sprawę, że po zalogowaniu się status pozostał niezmieniony i nie pozwoliłbym nikomu na zalogowanie się. Postanowiłem usunąć pliki cookie na początku każdego uwierzytelnienia, aby temu zapobiec.

private void DeleteFacebookCookie()
{
    //Set the current user cookie to have expired yesterday
    string cookie = String.Format("c_user=; expires={0:R}; path=/; domain=.facebook.com", DateTime.UtcNow.AddDays(-1).ToString("R"));
    Application.SetCookie(new Uri("https://www.facebook.com"), cookie);
}
Brak nowych kont

Umożliwienie użytkownikowi utworzenia nowego konta doprowadziło do dziwnego doświadczenia z interfejsem użytkownika. W moich przypadkach użycia użytkownik powinien mieć już konto eksytujące. Wyłączyłem to, sprawdzając, czy użytkownik został przekierowany do „r.php /”, czyli tego, co Facebook wykorzystuje do utworzenia nowego konta.

private void webBrowser_Navigating(object sender, System.Windows.Navigation.NavigatingCancelEventArgs e)
{
    if (e.Uri.LocalPath == "/r.php")
    {
        MessageBox.Show("To create a new account go to www.facebook.com", "Could Not Create Account", MessageBoxButton.OK, MessageBoxImage.Error);
        e.Cancel = true;
    }
}
Obsługa window.close ()

Przycisk Anuluj w oknie Facebooka pokazuje możliwość zamknięcia okna. Musiałem to złapać i zamknąć okno. Nie miałem pojęcia, jak to się stało, ale widziałem, że w MessageHook mogłem zobaczyć, że ostatnia wiadomość do wysłania (int msg) za każdym razem wynosiła 130, więc po prostu wysłuchałem 130. To niedbałe, ale działa.

IntPtr webBrowser_MessageHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
    //msg = 130 is the last call for when the window gets closed on a window.close() in javascript
    if (msg == 130)
    {
        this.Close();
    }
    return IntPtr.Zero;
}
streszczenie

Korzystanie z kodu jest bardzo proste

FacebookAuthenticationWindow dialog = new FacebookAuthenticationWindow() { AppID = "YOURAPPID" };
if(dialog.ShowDialog() == true)
{
    string accessToken = dialog.AccessToken;
    //The world is your oyster
}

Mam nadzieję, że ten przykład jest pomocny dla społeczności. Naprawdę chciałbym usłyszeć od każdego, kto ma jakiekolwiek ulepszenia, spostrzeżenia, a nawet krytykę.

~ Mo

questionAnswers(0)

yourAnswerToTheQuestion