WPF和C#中的Facebook OAuth示例

我正在开发一个WPF应用程序,要求我使用oAuth从Facebook获取访问令牌。 经过多次在线搜索,我得出以下结论:

  1. OAuth必须在浏览器中完成
  2. 我需要在该浏览器中查看URLpost,因此它必须位于WebBrowser WPF控件中

我决定创建一个用于进行Facebook身份validation的modal dialog,我可以使用访问令牌而忽略其余部分。 我想继续使用MVVM模型,但它比我预期的要困难。 关于如何做到这一点的任何想法都会非常有帮助

以下是我实现的一些function

  • Cookie删除因此可以让另一个用户进行身份validation,而无需将当前用户注销
  • 禁用新帐户创建,因为它导致了奇怪的UI体验
  • 从Facebook生成的javascript中收听取消按钮

WPF窗口

WPF非常简单。 从本质上讲,它只是一个WebBrowser控件,其中包含Navigated和Navigating事件。

    

代码

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

获取访问令牌

我忘记了我在哪里得到这个代码(如果有人能提醒我,以便我可以给予适当的信任,我将不胜感激)。

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

删除Cookie

我意识到,在有人登录后,状态保持这种状态并且不允许其他人登录。我决定在每次认证开始时删除cookie以防止这种情况发生。

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

没有新帐户

允许用户创建新帐户会导致奇怪的UI体验。 对于我的用例,用户应该已经拥有一个现有帐户。 我通过检查用户是否被重定向到“r.php /”来禁用它,这是Facebook用来创建新帐户的。

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

处理window.close()

Facebook对话框中的取消按钮显示关闭窗口的function。 我需要抓住这个并确保关闭窗口。 我不知道怎么,但是我在MessageHook中看到我能够看到每次发送的最后一条消息(int msg)是130,所以我只听了130.它很草率,但它有效。

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

摘要

使用代码非常简单

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

我希望这个例子对社区有所帮助。 我真的很想听到有任何改进,见解甚至批评的人。

莫〜