Obtaining a Facebook Auth Token for a Command-Line (Desktop) Application

Obtaining a Facebook auth token for a command-line (desktop) application

So, I finally got it working, without setting up a web server and doing a callback. The trick, counter-intuitively, was to turn off the "Desktop application" setting and not to request offline_access.

FaceBook::Graph's support for posting videos doesn't seem to work at the moment, so I ended up doing it in Ruby.

fb_auth = FbGraph::Auth.new(APP_ID, APP_SECRET)

client = fb_auth.client
client.redirect_uri = "https://www.facebook.com/connect/login_success.html"

if ARGV.length == 0
puts "Go to this URL"
puts client.authorization_uri(:scope => [:publish_stream, :read_stream] )
puts "Then run me again with the code"
exit
end

if ARGV.length == 1
client.authorization_code = ARGV[0]
access_token = client.access_token! :client_auth_body
File.open("authtoken.txt", "w") { |io| io.write(access_token) }
exit
end

file, title, description = ARGV

access_token = File.read("authtoken.txt")
fb_auth.exchange_token! access_token
File.open("authtoken.txt", "w") { |io| io.write(fb_auth.access_token) }

me = FbGraph::Page.new(PAGE_ID, :access_token => access_token)
me.video!(
:source => File.new(file),
:title => title,
:description => description
)

Trying to authenticate and read newsfeed/timeline (C# Desktop application)

In general, it is quite hard to authenticate a User in a desktop application. Have a look at my answer to the question Obtaining a Facebook auth token for a command-line (desktop) application The only chance is using a WebView.

It is possible to exchange short-lived Access Tokens into long-lived ones: https://developers.facebook.com/docs/facebook-login/access-tokens/#extending

Concerning your questions:

  1. Yes, but only in a way as descibed in my answer linked above
  2. You can use the following endpoints, depending on what you want to achieve:

    • Feed (with it's filtered versions) https://developers.facebook.com/docs/graph-api/reference/user/feed/
    • Home https://developers.facebook.com/docs/graph-api/reference/user/home/

How to generate Facebook User Access Token using curl

You can´t get ANY Token without an App, but you don´t need to program anything in order to get a User Token. These articles explain everything in detail:

  • https://developers.facebook.com/docs/facebook-login/access-tokens
  • http://www.devils-heaven.com/facebook-access-tokens/
  • https://developers.facebook.com/docs/facebook-login/

For example, you can use the API Explorer to select your App and generate User Tokens.

How to authenticate facebook command line app (Ruby)

This isn't currently possible with Open Graph applications without sharing a server-side authentication token. Facebook requires you maintain control (and not share) your Applications authentication token. If a user were to abuse the command line application, and make a large number of requests to the server, using your app ID and token, you would be the one on the hook.

The best way to accomplish your goal is with a server under your control in between your command line application and the Facebook graph api. The command-line api could direct the user to your website where they would hit the "Facebook Connect" button. The user would authenticate the application with your server, and you could provide them with a token they could pair with their user ID to post status updates or retrieve friends through your server.

The command-line api would interact with your server, and your server with the Facebook Graph API.

A strong side benefit of this approach is that if Facebook's API changes, your clients would not break (no need to change your own server's API).

Facebook Authentication for Desktop (Console based) application

Maybe you can have some setup process where you obtain the tokens with offline access, that way the user will need to be presented with facebook login page only once, then you use this token later with the console app.

See offline_access on http://developers.facebook.com/docs/authentication/permissions/

Facebook Access Token - Automate Getting the Token

This code will automate the retrieval of the access_token. You must have credentials to the account you are requesting an access token for.

Updated

First login to the facebook account.

        // LOG INTO FACEBOOK ACCT
string email = "youremail@blah.com";
string pw = "yourPassWord";

CookieContainer cookieJar = new CookieContainer();

HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("https://www.facebook.com");
request1.CookieContainer = cookieJar;

request1.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";

//Get the response from the server and save the cookies from the first request..
HttpWebResponse response = (HttpWebResponse)request1.GetResponse();
var cookies = response.Cookies;
cookieJar.Add(cookies);
response.Close();// close the response

string getUrl = "https://www.facebook.com/login.php?login_attempt=1";

string postData = String.Format("email={0}&pass={1}", email, pw);
HttpWebRequest getRequest = (HttpWebRequest)WebRequest.Create(getUrl);
getRequest.CookieContainer = cookieJar;
//Adding Previously Received Cookies
getRequest.CookieContainer.Add(cookies);
getRequest.Method = WebRequestMethods.Http.Post;
getRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";
getRequest.AllowWriteStreamBuffering = true;
getRequest.ProtocolVersion = HttpVersion.Version11;
getRequest.AllowAutoRedirect = true;
getRequest.ContentType = "application/x-www-form-urlencoded";

byte[] byteArray = Encoding.ASCII.GetBytes(postData);
getRequest.ContentLength = byteArray.Length;
Stream newStream = getRequest.GetRequestStream(); //open connection
newStream.Write(byteArray, 0, byteArray.Length); // Send the data.
newStream.Close();

HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse();
using (StreamReader sr = new StreamReader(getResponse.GetResponseStream()))
{
string sourceCode = sr.ReadToEnd();
}

Then request the access_token

                ApplicationId = request.ClientId; // your application id
string permissions = "['ads_management', 'ads_read']";

var destinationURL = String.Format(
@"https://www.facebook.com/dialog/oauth?client_id={0}&scope={1}&redirect_uri=http://www.kb-demos.com/login_success.html&response_type=token",
ApplicationId,
permissions);

// Create a new 'HttpWebRequest' Object to the mentioned URL.
HttpWebRequest myHttpWebRequest = (HttpWebRequest)WebRequest.Create(destinationURL);
// use the same cookie container and cookies
myHttpWebRequest.CookieContainer = cookieJar;
myHttpWebRequest.CookieContainer.Add(cookies); //recover cookies First request

myHttpWebRequest.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36";

myHttpWebRequest.AllowAutoRedirect = false;
// Assign the response object of 'HttpWebRequest' to a 'HttpWebResponse' variable.
HttpWebResponse myHttpWebResponse = (HttpWebResponse)myHttpWebRequest.GetResponse();

Console.WriteLine("\nThe Request HttpHeaders are \n\n\tName\t\tValue\n{0}", myHttpWebRequest.Headers); // my http headers
Console.WriteLine("\nThe Request HttpHeaders are \n\n\tName\t\tValue\n{0}", myHttpWebRequest.CookieContainer); // my http headers
//Console.WriteLine("\nThe Request HttpHeaders are \n\n\tName\t\tValue\n{0}", cookies); // my http headers

var headers = myHttpWebResponse.Headers;
// output all the headers
foreach (var header in headers)
{
Console.WriteLine(header.ToString() + ": " + headers[header.ToString()] + "\n");

}

var cow = GetParams(headers["Location"]);
string accessToken = "";
accessToken = cow["#access_token"];

And the helper method

    /// <summary>
/// Helper method to get Params from URL using RegEx
/// </summary>
static Dictionary<string, string> GetParams(string uri)
{
var matches = Regex.Matches(uri, @"[\?&](([^&=]+)=([^&=#]*))", RegexOptions.Compiled);
return matches.Cast<Match>().ToDictionary(
m => Uri.UnescapeDataString(m.Groups[2].Value),
m => Uri.UnescapeDataString(m.Groups[3].Value)
);
}

Long-lasting FB access-token for server to pull FB page info

These are the steps that were previously in the question - they have been migrated to this answer.

Having found that it is possible to generate a Facebook Page Access Token that does not expire (with help from @Igy), here is a clear, step-by-step quide for all those looking to the same:

  1. Make sure you are the admin of the FB page you wish to pull info from
  2. Create a FB App (should be with the same user account that is the page admin)
  3. Head over to the Facebook Graph API Explorer
  4. On the top right, select the FB App you created from the "Application" drop down list
  5. Click "Get Access Token"
  6. Make sure you add the manage_pages permission
  7. Convert this short-lived access token into a long-lived one by making this Graph API call:
    https://graph.facebook.com/oauth/access_token?client_id=<your FB App ID >&client_secret=<your FB App secret>&grant_type=fb_exchange_token&fb_exchange_token=<your short-lived access token>
  8. Grab the new long-lived access token returned back
  9. Make a Graph API call to see your accounts using the new long-lived access token: https://graph.facebook.com/me/accounts?access_token=<your long-lived access token>
  10. Grab the access_token for the page you'll be pulling info from
  11. Lint the token to see that it is set to Expires: Never!

That should do it. You should now have a Facebook Page Access Token that doesn't expire, unless:

  • You change your Facebook account password
  • You lose admin access for the target page
  • You delete or de-authorize your Facebook App

Any of these will cause the access token to become invalid.

If you are getting (#100) Tried accessing nonexisting field (accounts) on node type (Page), go to the Access Token Debugger, copy the value of User ID, and use it to replace the "me" part of the URL in step 9.



Related Topics



Leave a reply



Submit