I am trying to develop a Windows Phone 7 application using Facebook login and logout operations. I found Facebook SDK and used it in order to carry out login, by opening WebBrowser. The user enters credentials to this browser and logs in successfully. Moreover, I managed to login the user without using any SDK, just using http requests, like the SDK actually does. However, I want to logout users without using any WebBrowser, but just clicking a button for example. There are so many solutions in the web suggesting that I should open web browser and navigate it to a certain URL in order to logout. However, this is not what I want. I think there should be a way to logout by clearing cookies, which I dont exactly know how to do, or any other that you suggest. Some part of my code below:
private static String appID = "";
private static String appSecret = "";
public static void login(String[] permissions)
{
try
{
permissionArray = permissions;
popup = new Popup();
popup.Height = 480;
popup.Width = 480;
popup.VerticalOffset = 100;
FacebookLoginUserControl control = new FacebookLoginUserControl();
control.facebookWebBrowser.Loaded += new RoutedEventHandler(webBrowser_Loaded);
control.facebookWebBrowser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(webBrowser_Navigated);
popup.Child = control;
popup.IsOpen = true;
}
catch (Exception e)
{
//handle
}
}
private static void webBrowser_Loaded(Object sender, RoutedEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
String loginUrl = GetFacebookLoginUrl();
wb.Navigate(new Uri(loginUrl));
}
private static String GetFacebookLoginUrl()
{
String permissionString = String.Empty;
if (permissionArray.Length > 0)
permissionString = String.Join(",", permissionArray);
var uriParams = new Dictionary<string, string>() {
{"client_id", appID},
{"response_type", "token"},
{"scope", permissionString},
{"redirect_uri", "http://www.facebook.com/connect/login_success.html"},
{"display", "touch"}
};
StringBuilder urlBuilder = new StringBuilder();
foreach (var current in uriParams)
{
if (urlBuilder.Length > 0)
{
urlBuilder.Append("&");
}
var encoded = HttpUtility.UrlEncode(current.Value);
urlBuilder.AppendFormat("{0}={1}", current.Key, encoded);
}
var loginUrl = "http://www.facebook.com/dialog/oauth?" + urlBuilder.ToString();
return loginUrl;
}
private static void webBrowser_Navigated(Object sender, System.Windows.Navigation.NavigationEventArgs e)
{
if (string.IsNullOrEmpty(e.Uri.Fragment)) return;
if (e.Uri.AbsoluteUri.Replace(e.Uri.Fragment, "") == "http://www.facebook.com/connect/login_success.html")
{
string text = HttpUtility.HtmlDecode(e.Uri.Fragment).TrimStart('#');
var pairs = text.Split('&');
foreach (var pair in pairs)
{
var kvp = pair.Split('=');
if (kvp.Length == 2)
{
if (kvp[0] == "access_token")
{
accessToken = kvp[1];
MessageBox.Show("Access granted");
RequestUserProfile();
}
}
}
if (string.IsNullOrEmpty(accessToken))
{
MessageBox.Show("Unable to authenticate");
}
popup.IsOpen = false;
}
}
private static void RequestUserProfile()
{
var profileUrl = string.Format("https://graph.facebook.com/me?access_token={0}", HttpUtility.UrlEncode(accessToken));
request = (HttpWebRequest)HttpWebRequest.Create(new Uri(profileUrl));
request.Method = "GET";
request.BeginGetResponse(result =>
{
try
{
var resp = (result.AsyncState as HttpWebRequest).EndGetResponse(result);
using (var strm = resp.GetResponseStream())
{
StreamReader sr = new StreamReader(strm);
var responseString = sr.ReadToEnd();
}
}
catch (Exception ex)
{
//
}
}, request);
}
Any Ideas to solve the problem.
Thanks in advance
What's actually so spooky in using webBrowser? If you programmatically create a WebBrowser object, it won't be visible, unless you'd add it somewhere on form/page. If you want to clear cookies for Facebook, the solution will be something like that:
// Can be invoked from your button_click event
public void TryLogout()
{
webBrowser = new WebBrowser();
Uri uri = new Uri("http://m.facebook.com/home.php?r", UriKind.Absolute);
webBrowser.LoadCompleted += new LoadCompletedEventHandler(webBrowser_TryLogoutLoadCompleted);
webBrowser.Navigate(uri);
}
And then:
private void webBrowser_TryLogoutLoadCompleted(object sender, EventArgs e)
{
try
{
var cookies = webBrowser.GetCookies();
foreach (Cookie cookie in cookies)
{
if (cookie.Domain.Contains("m.facebook.com"))
{
cookie.Discard = true;
cookie.Expired = true;
}
}
// we've just cleaned up cookies
}
finally
{
webBrowser.LoadCompleted -= webBrowser_TryLogoutLoadCompleted;
}
}
Hope this helps.
GetCookies method
Related
I'm creating simple launcher for my other application and I need advise on logical part of the program. Launcher needs to check for connection, then check for file versions (from site), compare it with currently downloaded versions (if any) and if everything is alright, start the program, if not, update (download) files that differs from newest version. The files are:
program.exe, config.cfg and mapFolder. The program.exe and mapFolder must be updated, and config.cfg is only downloaded when there is no such file. Additionaly mapFolder is an folder which contains lots of random files (every new version can have totally different files in mapFolder).
For the file version I thought I would use simple DownloadString from my main site, which may contain something like program:6.0,map:2.3, so newest program ver is 6.0 and mapFolder is 2.3. Then I can use FileVersionInfo.GetVersionInfo to get the version of current program (if any) and include a file "version" into mapFolder to read current version.
The problem is I dont know how to download whole folder using WebClient and what's the best way to do what I want to do. I've tried to download the mapFolder as zip and then automatically unpack it, but the launcher need to be coded in .net 3.0.
Here is my current code, that's just a prototype to get familiar with whole situation, dont base on it.
`
WebClient wc = new WebClient();
string verifySite = "google.com/downloads/version";
string downloadSite = "google.com/downloads/program.exe";
Uri verifyUri, downloadUri = null;
string userVer, currVer = "";
string downloadPath = Directory.GetCurrentDirectory();
string clientName = "program.exe";
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
wc.DownloadFileCompleted += new AsyncCompletedEventHandler(FileDownloaded);
wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(FileDownloadProgress);
chckAutorun.Checked = Properties.Settings.Default.autorun;
checkConnection();
if(!checkVersion())
downloadClient();
else
{
pbDownload.Value = 100;
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
}
private bool checkConnection()
{
verifyUri = new Uri("http://" + verifySite);
downloadUri = new Uri("http://" + downloadSite);
WebRequest req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
verifyUri = new Uri("https://" + verifySite);
downloadUri = new Uri("https://" + downloadUri);
req = WebRequest.Create(verifyUri);
try
{
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return true;
}
catch { }
return false;
}
private void downloadClient()
{
try
{
wc.DownloadFileAsync(downloadUri, Path.Combine(downloadPath, clientName));
}
catch { }
}
private bool checkVersion()
{
lblProgress.Text = "checking for updates";
try
{
currVer = FileVersionInfo.GetVersionInfo(Path.Combine(downloadPath, clientName)).FileVersion;
}
catch {
currVer = "";
}
try
{
userVer = wc.DownloadString(verifyUri);
}
catch {
userVer = "";
}
return currVer == userVer && currVer != "";
}
private void FileDownloaded(object sender, AsyncCompletedEventArgs e)
{
btnPlay.Enabled = true;
lblProgress.Text = "updated";
if (chckAutorun.Checked)
btnPlay.PerformClick();
}
private void FileDownloadProgress(object sender, DownloadProgressChangedEventArgs e)
{
long received = e.BytesReceived / 1000;
long toReceive = e.TotalBytesToReceive / 1000;
lblProgress.Text = string.Format("{0}KB {1}/ {2}KB", received, Repeat(" ", Math.Abs(-5 + Math.Min(5, received.ToString().Length))*2), toReceive);
pbDownload.Value = e.ProgressPercentage;
}
private void btnPlay_Click(object sender, EventArgs e)
{
btnPlay.Enabled = false;
if(checkVersion())
{
lblProgress.Text = "Starting...";
Process.Start(Path.Combine(downloadPath, clientName));
this.Close();
}
else
{
downloadClient();
}
}
public static string Repeat(string instr, int n)
{
if (string.IsNullOrEmpty(instr))
return instr;
var result = new StringBuilder(instr.Length * n);
return result.Insert(0, instr, n).ToString();
}
private void chckAutorun_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.autorun = chckAutorun.Checked;
Properties.Settings.Default.Save();
}`
I've managed to achieve what I need by enabling autoindex on web server and download string of files in folder ending with .map .
string mapSite = wc.DownloadString(new Uri("http://" + mapsSite));
maps = Regex.Matches(mapSite, "<a href=\"(.*).map\">");
foreach (Match m in maps)
{
string mapName = m.Value.Remove(0, 9).Remove(m.Length - 11);
downloaded = false;
wc.DownloadFileAsync(new Uri("http://" + mapsSite + mapName), Path.Combine(downloadPath, #"mapFolder/" + mapName));
while (!downloaded) { }
}
This question already has answers here:
Facebook JS SDK's FB.api('/me') method doesn't return the fields I expect in Graph API v2.4+
(4 answers)
Closed 7 years ago.
I am trying to access user's information through a Facebook Login page in my WinForm application. Even though I ask for user's email in extended permissions, all I get after submit is the name and the id.
public partial class Form1 : Form
{
private const string AppId = "MY_APP_ID_IS_HERE";
private Uri loginUrl;
private const string extendedPermissions = "public_profile,user_friends,email";
FacebookClient fbClient = new FacebookClient();
private string _accessToken;
private bool _authorized;
private string _currentName;
private string _currentEmail;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Login();
}
private void Login()
{
dynamic parameters = new ExpandoObject();
parameters.client_id = AppId;
parameters.redirect_uri = "https://www.facebook.com/connect/login_success.html";
parameters.response_type = "token";
parameters.display = "popup";
if (!string.IsNullOrWhiteSpace(extendedPermissions))
parameters.scope = extendedPermissions;
var fb = new FacebookClient();
loginUrl = fb.GetLoginUrl(parameters);
webBrowser1.Navigate(loginUrl.AbsoluteUri);
}
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
if (webBrowser1.Visible)
{
var fb = new FacebookClient();
FacebookOAuthResult oauthResult;
if (fb.TryParseOAuthCallbackUrl(e.Url, out oauthResult))
{
if (oauthResult.IsSuccess)
{
_accessToken = oauthResult.AccessToken;
_authorized = true;
}
else
{
_accessToken = "";
_authorized = false;
}
if (_authorized)
{
fb = new FacebookClient(_accessToken);
dynamic result = fb.Get("me");
_currentName = result.name;
_currentEmail = result.email;
lblLoggedInUser.Text = string.Format("Facebook User: {0}", _currentName);
lblPassword.Text = string.Format("Email: {0}", _currentEmail);
//Do what need being done now that we are logged in!
}
else
{
MessageBox.Show("Couldn't log into Facebook!", "Login unsuccessful", MessageBoxButtons.OK,
MessageBoxIcon.Error);
}
}
}
}
}
When I run the query and ask for the user's email using Facebook Graph API Explorer, it returns this debug message:
Apparently my program is not asking for permission to use user's email. Because immediately after I submit my login a white page with the text "Success" is shown and no value for email is returned.
How can I change my login page to ask for user's email?
Try
dynamic result = fb.Get("me?fields=id,name,email");
I am working on windows application. I get gmail contact using following code.
But in this case I must login and accept permission from browser form(GoogleLoginForm).
I want to skip this "oauth dialog".
I have referred almost link of stack overflow and google developer. But I don't get much help regarding to this. Is there anyway to skip the permission from browser?
Please suggest.
This is my main form.
string SCOPE = "https://www.google.com/m8/feeds/ https://apps-apis.google.com/a/feeds/groups/";
string REDIRECT_URI = "urn:ietf:wg:oauth:2.0:oob";
OAuth2Parameters parameters = new OAuth2Parameters();
parameters.ClientId = CLIENT_ID;
parameters.ClientSecret = CLIENT_SECRET;
parameters.RedirectUri = REDIRECT_URI;
parameters.Scope = SCOPE;
string url = OAuthUtil.CreateOAuth2AuthorizationUrl(parameters);
Uri loginUri = new Uri(url);
GoogleLoginForm objForm = new GoogleLoginForm(loginUri);
DialogResult result= objForm.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
parameters.AccessCode = objForm._OAuthVerifierToken;
}
OAuthUtil.GetAccessToken(parameters);
RequestSettings reqSettings = new RequestSettings("myapplication", parameters) { AutoPaging = true };
ContactsRequest contReq = new ContactsRequest(reqSettings);
Feed<Google.Contacts.Contact> Contacts = contReq.GetContacts();
I get AccessCode by following code.
public GoogleLoginForm(Uri url)
{
InitializeComponent();
_loginUri = url;
}
public GoogleLoginForm(Uri loginUri)
{
// TODO: Complete member initialization
this._loginUri = loginUri;
}
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
string fullPath = e.Url.ToString();
WebBrowser control = sender as WebBrowser;
if (control != null && !string.IsNullOrEmpty(control.DocumentTitle) && control.DocumentTitle.Contains("Success code"))
{
_OAuthVerifierToken = control.DocumentTitle.Replace("Success code=", "");
DialogResult = DialogResult.OK;
}
}
private void GoogleLoginForm_Load(object sender, EventArgs e)
{
webBrowser1.Url = _loginUri;
}
I'm having a problem retrieving the access token from the redirect uri. When I try my coded procedure on my mozilla I get redirected to my localhost with the access token, but how do I instantiate this with my webBrowser in C#?
My current code looks like this:
public partial class Form1 : Form
{
public string client_id = "CLIENT_ID";
public string client_secret= "CLIENT_SECRET";
public string redirect_uri = "http://localhost:5050";
public Form1()
{
InitializeComponent();
webBrowser.AllowNavigation = true;
webBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
webBrowser.Navigate(String.Format("https://accounts.google.com/o/oauth2/auth?response_type=code&scope=email+profile&redirect_uri={0}&client_id={1}&hl=de&from_login=1&as=d832bdaf61552d&pli=1&authuser=0"
,redirect_uri, client_id));
}
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = sender as WebBrowser;
//MessageBox.Show(wb.Url.ToString());
if (wb.Url.ToString().StartsWith("http://localhost"))
{
String[] s = wb.Url.ToString().Split('=');
string authCode = s[s.Length - 1];
MessageBox.Show("auth Code: " + authCode);
//WebClient wc = new WebClient();
//var data = new NameValueCollection();
//data["code"] = authCode;
//data["client_id"] = client_id;
//data["client_secret"] = client_secret;
//data["redirect_uri"] = "http://localhost:5050";
//data["grant_type"] = "authorization_code";
//var response = wc.UploadValues("accounts.google.com/o/oauth2/token", "POST", data);
//foreach (byte a in response)
//{
// MessageBox.Show(a.ToString());
//}
}
}
If you know how to do this with the GoogleDrive API please share it with me.
Please Use UIWebBrowser instead of WebBrowser and your code should like this.
public Form1()
{
InitializeComponent();
UIWebBrowser.AllowNavigation = true;
UIWebBrowser.DocumentCompleted += webBrowser_DocumentCompleted;
UIWebBrowser.Navigate(String.Format("https://accounts.google.com/o/oauth2/auth?response_type=code&scope=email+profile&redirect_uri={0}&client_id={1}&hl=de&from_login=1&as=d832bdaf61552d&pli=1&authuser=0"
,redirect_uri, client_id));
}
void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (e.Url.AbsoluteUri.StartsWith("http://localhost"))
{
// Redirect so we end up with a blank web browser control
UIWebBrowser.Navigate("about:blank");
code = e.Url.Query;
}
}
I am trying to add Facebook into my application. I have try with a sample.
public class FacebookLoginPageViewModel
{
private static WebBrowser _webBrowser;
private Page _page;
private const string ExtendedPermissions = "user_about_me,read_stream,publish_stream,user_birthday,offline_access,email";
private readonly FacebookClient _fb = new FacebookClient();
private const string AppId = "1XXX58XXXXXXXX9";
Uri url;
public FacebookLoginPageViewModel(Panel container, Page page)
{
_page = page;
_webBrowser = new WebBrowser();
var loginUrl = GetFacebookLoginUrl(AppId, ExtendedPermissions);
url = loginUrl;
container.Children.Add(_webBrowser);
_webBrowser.Navigated += webBrowser_Navigated;
_webBrowser.Navigate(loginUrl);
}
private Uri GetFacebookLoginUrl(string appId, string extendedPermissions)
{
var parameters = new Dictionary<string, object>();
parameters["client_id"] = appId;
parameters["redirect_uri"] = "https://www.facebook.com/connect/login_success.html";
parameters["response_type"] = "token";
parameters["display"] = "touch";
// add the 'scope' only if we have extendedPermissions.
if (!string.IsNullOrEmpty(extendedPermissions))
{
// A comma-delimited list of permissions
parameters["scope"] = extendedPermissions;
}
return _fb.GetLoginUrl(parameters);
}
void webBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
FacebookOAuthResult oauthResult;
if (!_fb.TryParseOAuthCallbackUrl(e.Uri, out oauthResult))
{
return;
}
if (oauthResult.IsSuccess)
{
var accessToken = oauthResult.AccessToken;
LoginSucceded(accessToken);
}
else
{
// user cancelled
MessageBox.Show(oauthResult.ErrorDescription);
}
}
private void LoginSucceded(string accessToken)
{
var fb = new FacebookClient(accessToken);
fb.GetCompleted += (o, e) =>
{
if (e.Error != null)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
MessageBox.Show(e.Error.Message);
return;
});
}
var result = (IDictionary<string, object>)e.GetResultData();
var id = (string)result["id"];
var url = string.Format("/Views/FacebookInfoPage.xaml?access_token={0}&id={1}", accessToken, id);
var rootFrame = (App.Current as App).RootFrame;
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
rootFrame.Navigate(new Uri(url, UriKind.Relative));
});
};
fb.GetAsync("me?fields=id");
}
This is working fine. But i want to Log out from the facebook when i click log out. How to achieve this? I have try with some examples. But it is not working for me.
private void logout(object sender, RoutedEventArgs e)
{
webBrowser1.Navigated +=
new EventHandler<System.Windows.Navigation.NavigationEventArgs>(CheckForout);
webBrowser1.Navigate(new Uri("http://m.facebook.com/logout.php?confirm=1"));
webBrowser1.Visibility = Visibility.Visible;
}
private void CheckForout(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
string fbLogoutDoc = webBrowser1.SaveToString();
Regex regex = new Regex
("\\<a href=\\\"/logout(.*)\\\".*data-sigil=\\\"logout\\\"");
MatchCollection matches = regex.Matches(fbLogoutDoc);
if (matches.Count > 0)
{
string finalLogout = string.Format("http://m.facebook.com/logout{0}",
matches[0].Groups[1].ToString().Replace("amp;", ""));
webBrowser1.Navigate(new Uri(finalLogout));
}
}
Please let me any idea to resolve this problem.
i got one more example:
https://www.facebook.com/logout.php?next=YOUR_URL&access_token=ACCESS_TOKEN
i have try like this:
string newURL = string.Format("https://www.facebook.com/logout.php?next={0}&access_token={1}", _userId, _accessToken);
But here what i have to pass to the YOUR_URL???
I found the solution.
public static void logoutSession()
{
_webBrowser.Navigated += new EventHandler<System.Windows.Navigation.NavigationEventArgs>(CheckForout);
string logoutUrl = "https://www.facebook.com/connect/login_success.html";
string newURL = string.Format("https://www.facebook.com/logout.php?next={0}&access_token={1}", logoutUrl, access_tocken);
_webBrowser.Navigate(new Uri(newURL));
}
public static void CheckForout(object sender, System.Windows.Navigation.NavigationEventArgs e)
{
string fbLogoutDoc = _webBrowser.SaveToString();
Regex regex = new Regex
("\\<a href=\\\"/logout(.*)\\\".*data-sigil=\\\"logout\\\"");
MatchCollection matches = regex.Matches(fbLogoutDoc);
if (matches.Count > 0)
{
string finalLogout = string.Format("http://m.facebook.com/logout{0}",
matches[0].Groups[1].ToString().Replace("amp;", ""));
_webBrowser.Navigate(new Uri(finalLogout));
}
}
This will log out from the facebook in windows phone 7.