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 WPFPostanowił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 WPFWPF 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ępuZapomniał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 cookieZdał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 kontUmoż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;
}
streszczenieKorzystanie 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