Facebook Access Token questions - facebook-graph-api

I'm playing around with Facebook Connect, trying to use Facebook as the means or authentication on my site. Currently my workflow looks something like this:
Go to URL
Server checks cookies for AccessToken
If AccessToken exists, automatically fill in user's name/profile picture in comment box, and leave AccessToken in hidden input
send page down to client
on submit, verify access token (which was submitted with the rest of the form) is a valid access token for a real person. If so, add comment to Database
refresh page to display new data
if no access token, replace user's name/profile picture with <fb:login-button>, along with the required <script>s.
send page down to client
When user authorizes page/logs into facebook, refresh page
(go back to top, except this time the access token should exist)
So I have a few questions:
Is this secure? I was thinking of ways i would be able to do without the double authentication with Facebook (checking once on page-generation and checking again on comment-submission), and I could not figure any other way short of maintaining my own session-state with each client. Is that worth doing?
Does the access token expire when i log out of Facebook? I'm thinking it should, but it seems I can continue to use the same access token to grab data (i.e. name, url, etc.) after I manually go to Facebook and log myself out. Is it because I'm only asking for public information, and only more intrusive permissions expire on logout?
Given that each person who wants to do something has to provide a unique token from Facebook, this should have the side effect of blocking CSRF, since every action can be traced to a valid Facebook account. Is that right?

Why don't you just use the Facebook Javascript SDK to detect if they're currently logged into Facebook? This will also make the access token available in Javascript so you can make client-side calls to the API.
You can access the same access token server side via the session cookie set by Facebook also.

I can't answer all of your questions but I can tell you that having the access token in a hidden field on your page is risky from a policy perspective, especially if your page can be read by any third-party code such as Google Analytics or AdSense. Facebook will nail you for this as it is leaking user identifying data to third parties. The Facebook userid is in the access token in plain text. Facebook has automated processes that scan for this stuff and will auto-ban your app if it is leaking userids to third parties.

Related

Facebook Graph API - complete server side auth and API calls

I have an application, that runs on server. On that server is background task, that will post status update on few social networks (Facebook, Twitter, G+). It must be completely server-side.
In Twitter API I'm able to use OAuth header to authorize API request. OAuth HTTP header uses consumer key, consumer secret, access token and access token secret to create the header. With this I'm able to post/update/delete tweets with no user interaction.
How can I do this for Facebook? I found a solution to obtain a long-lived access_token (2 months), but we don't want to regenerate access_token every 60 days. We want to use it for manage our Facebook page - post status updates, but completely server-side.
Am I able to do this for Facebook? Thanks for answers.
PS: I searched stackoverflow hundred-times but with no solution for my problem.
Thanks.
It is not possible for User Access Tokens (they can only be extended to 60 days and need to be refreshed by the user after that), but for posting to a Page you should use a Page Token anyway. An Extended Page Token is valid forever.
Here are some Links to help you get that Extended Page Token:
https://developers.facebook.com/docs/facebook-login/access-tokens/
http://www.devils-heaven.com/facebook-access-tokens/
http://www.devils-heaven.com/extended-page-access-tokens-curl/
A Page Token will post "as Page" btw, but that´s probably what you want. And auto-posting on user profiles is not really allowed anyway, every message has to be 100% user generated and every posting should get authorized by the user.
Pay attention to Access Tokens Expiration & Extentions.
The Page Access Token could be a good solution to only server side calls for testing and data analysis purposes.
Take your User Access Token from Graph API Tool
Extend your User Access Token
Call https://graph.facebook.com/v2.11/me/accounts with your user access token extended
*all calls are GET and this procedure does not use APP Access Token.

access_token expires? I'm trying to query a public post w/JS. Easier way?

Beginner here, and I've been getting lost in the Facebook developer docs and Google for hours. I'm sure this is a simple question, but I just need some direction.
What I'm trying to do: query latest post of a page owner from a public Facebook page with JavaScript and parse it to display within my own HTML (can't use a Social Plugin - I need custom control over HTML/CSS).
What I've got working so far:
var token = '<my_token>';
var query = 'fields=posts.limit(1)';
var request = 'https://graph.facebook.com/[mypage]?' + query + '&access_token=' + token;
$.getJSON(request, function(response) {
alert(response.posts.data[0].message);
});
This does work, however, the Access Token debugger says my access_token is going to expire in 2 months. Why? It's a public Facebook page, and I only want to query the page owner's latest comment. Do I really need to create a Facebook App and login via PHP to just to access this public information?
I'm doing the exact same thing with a Twitter feed and all I had to do was $.getJSON http://api.twitter.com/1/statuses/user_timeline/.json, completely in JavaScript.
It seems getting similar information from Facebook is much more difficult, but perhaps I'm going about it the wrong way?
This does work, however, the Access Token debugger says my access_token is going to expire in 2 months. Why?
Because that’s what user access tokens do.
Do I really need to create a Facebook App and login via PHP to just to access this public information?
For pages that are restricted in any way (based on age, country or for alcohol related content) you have to use a user access token, because that’s the only way Facebook can figure out whether you’re actually allowed to see the content or not.
If it’s your own page, then you could generate a page access token – those don’t expire by default, if you use a long-lived user access token to get them.
But you don’t want to expose that kind of token in client-side JavaScript, because everyone visiting your site could steal it from there and act on behalf of your page then.

Request a Page Access Token in C# SDK

As a proof of concept for a simple background application, I used the Graph API Explorer to create an access token for my app to post something to the wall of a page I maintain. It worked fine. Naturally, however, the token expires.
So now I'm trying to have the background application automatically request a new page access token each time it runs. And I'm having a lot of trouble finding a concrete definition of how to do that. There's no shortage of information regarding Facebook and Access Tokens, but nothing seems to demonstrate how to have a background application post to a page. (Not post to a user's wall, not display a login dialog to a user since it's a background application, etc.)
I can fetch an access token in code easily enough by reading the response from a web request to this URL:
https://graph.facebook.com/oauth/access_token?grant_type=client_credentials&client_id={MY_APP_ID}&client_secret={MY_APP_SECRET}
Of course, that "access token" doesn't work when trying to post to the page's wall. It says that the user hasn't authorized the application to perform this action. The action I'm performing is pretty simple:
var client = new FacebookClient(GetFacebookAccessToken());
dynamic parameters = new ExpandoObject();
parameters.message = "this is a test";
dynamic result = client.Post("{MY_PAGE_ID}/feed", parameters);
I've read in some places that I'll need to make a second request, using the first access token, to get the page access token. But I can't seem to find examples of how to do that.
Can someone shed some light on this for me?
I have a Facebook page.
I have a Facebook app which serves no other purpose than to provide a means for a local background application to access said page.
I just need that application to be able to authenticate so it can post something to the page.
(And if there's a step I need to perform in the Facebook UI to permanently give the application permission to do this, I think I've performed that step but it would be good to double check somehow.)
Edit: It's been described to me that I need to obtain a long-lived user access token and, using that, obtain a page access token. The theory is that said page access token won't expire. However, what's not clear to me is how one accomplishes this.
I've read the page describing the deprecation of offline_access, as well as the page describing server-side access. However, I'm clearly misunderstanding something. In the former, it references the latter for obtaining the proper token. The latter, however, includes steps for presenting a login to the user, having them accept permissions, and using the response from that login.
Being a background process that runs unattended, presenting any sort of question to a user (which would be me) isn't really an option. I've also been told that I can't do a one-time request from my browser to get an access token because that is, by definition, client-side interaction and not part of the necessary server-side flow. (It seems odd to me that the service would care if a RESTful request comes from a web browser vs. from an application, but I'm not familiar enough with OAuth or the Facebook API to really make that call.)
So, if I can perform some manual steps to get a permanent access token for the app to post to the Facebook page, what are those steps? Conversely, if I can perform some automated steps in the application to acquire access each time it runs, what are those steps?
(Making a few more API calls from the application adds a second or two of running time to an otherwise once-a-day process, so it makes no difference to me which approach to take.)
At first I just went into the Facebook Application settings and re-enabled the deprecated "offline access" permission. Said application settings can be found at a URL like this:
https://developers.facebook.com/apps/{APPLICATION_ID}/advanced
However, since everything keeps referring to that setting as being "deprecated" then I didn't want to use that as a long-term solution. It may get removed entirely, it may be unsafe in certain circumstances, etc. Better to use recommended functionality.
So here's what I was able to piece together from a scavenger hunt through updated documentation, outdated documentation, a sea of outdated internet posts, and PHP code which mostly made assumptions about functionality that aren't true in all cases...
Visit the Graph API Explorer and select your Facebook Application from the drop-down menu. Click "Get Access Token" and select the permissions you want. (For mine I went to the "Extended Permissions" tab and selected "Managed Pages" and "Publish Stream.") You will be prompted (in my browser it was in a new tab) with a familiar screen where the Facebook Application is asking you, the user, to grant it the permissions you just selected. (You've seen this before if you've ever agreed to use a Facebook Application before.)
The value it produces in the Graph API Explorer (a long string of random-ish characters) is your "Short Lived User Access Token."
As described here in "Scenario 4: Client-side OAuth and Extending Access_Token Expiration Time through New Endpoint" access this URL in your web browser:
https://graph.facebook.com/oauth/access_token?
client_id={APPLICATION_ID}
&client_secret={APPLICATION_SECRET}
&grant_type=fb_exchange_token
&fb_exchange_token={SHORT_LIVED_USER_ACCESS_TOKEN}
(You can obtain the {APPLICATION_SECRET} value on the basic settings page for your Facebook Application: https://developers.facebook.com/apps/{APPLICATION_ID}/summary)
This will return another Access Token as such:
access_token={LONG_LIVED_USER_ACCESS_TOKEN}&expires=5184000
This access_token value (another long string of random-ish characters) is your "Long Lived User Access Token." The expires value is in seconds, which translates into 60 days.
Now we hop over to the Page API reference and take a look at the section on Page Access Tokens. This, along with the basic structure of Graph API requests exemplified here (scroll down to the part where it shows a bulleted list of sample links which include access_token specifiers, which you'll need to specify here because you're requesting non-public information) leads you to request this in your browser:
https://graph.facebook.com/{FACEBOOK_USER_ID}/accounts?
access_token={LONG_LIVED_USER_ACCESS_TOKEN}
This will return a JavaScript object containing lots of useful information about the Facebook Pages and Facebook Applications your user account controls. In my case the Page and the Application had the same name, but it's easy to tell them apart from the category values or, if all else fails, the id values. Find the Page that the background application running on your machine will need to access and copy its access_token (the third and final long string of random-ish characters). The whole node looks something like this:
{
"name": "Some Facebook Application Name",
"access_token": "{LONG_LIVED_PAGE_ACCESS_TOKEN}",
"category": "Musician/band",
"id": "{APPLICATION_ID}",
"perms": [
"ADMINISTER",
"EDIT_PROFILE",
"CREATE_CONTENT",
"MODERATE_CONTENT",
"CREATE_ADS",
"BASIC_ADMIN"
]
}
This is your "Long Lived Page Access Token." This is the value you use to initialize the FacebookClient object in the code. Then, posting a simple status update is as easy as:
var client = new FacebookClient("{LONG_LIVED_PAGE_ACCESS_TOKEN}");
dynamic parameters = new ExpandoObject();
parameters.message = "This is a my status update.";
dynamic result = client.Post("{FACEBOOK_PAGE_ID}/feed", parameters);
Supposedly this "Long Lived Page Access Token" does not expire after 60 days like the "Long Lived User Access Token" does. I'll find out in 59 days, I guess.
NB: The curly braces in my examples are part of the placeholder for actual values. Do not use the curly braces in the actual requests. So something like this:
https://developers.facebook.com/apps/{APPLICATION_ID}/advanced
becomes something like this, for example:
https://developers.facebook.com/apps/123456/advanced
where 123456 is the actual Facebook Application ID.
Being a background process that runs unattended, presenting any sort of question to a user (which would be me) isn't really an option.
As I already said, you only have to do it once.
You get your non-expiring page access token, copy&paste that into your app – and from then on your app can do server-side whatever it wants to do happily everafter.
I've also been told that I can't do a one-time request from my browser to get an access token because that is, by definition, client-side interaction and not part of the necessary server-side flow.
The server-side auth flow for getting a user access token also needs to take part partly in the browser.
It does not matter, if you get a short-lived token via the client-side auth flow and extend it afterwards, or if you get a long-lived one using the server-side auth flow.
(It seems odd to me that the service would care if a RESTful request comes from a web browser vs. from an application […])
Facebook does not want users to give their login credentials to any third party. Therefor, the process of getting a user access token always has to take part in the browser, with the user login in to Facebook.
So, if I can perform some manual steps to get a permanent access token for the app to post to the Facebook page, what are those steps?
Get a long-lived user access token with manage_pages permission. (Or get a short-lived one, and extend it). And then, use that long-lived token to request a page access token for the target page, in the way that is described in the docs.

When should the server-side vs. client-side Facebook authentication flows be used?

Facebook has two flows for Authentication, client-side and server-side. When should each one be used?
Facebook docs: https://developers.facebook.com/docs/authentication/
Possibly related: What is the purpose of the implicit grant authorization type in OAuth 2?
Depending on your needs you can use one or the other or both. If you want calls to facebook to be processed before the user sees a certain page then use server side... however if you want to display partial information until the user has authenticated, use javascript authentication.
It boils down to this:
Javascript authentication can happen with-in a popup window and does not require a page reload you can also just perform a top.location.href redirect.
PHP authentication involves a redirect to an authentication page.
Also see this thread, in particular this response.
To add to #Lix's answer, I would say:
Client Side Authentication
When you want some information from Facebook API about the user that is required once, as in you only need to get it once like the user's name and email.
When you want to temporarily access/manage the user's information/data and don't need to do it often.
You get a temporary token, which is valid only for a few hours and you need to get a new token to call the Facebook API again after it has expired (which requires the user has to grant permission again).
Server Side Authentication
You want to manage the user's data (on their behalf) after the user has left your website/app. Example, gathering the user's feed/timeline data on a regular basis.
When you want to access/manage the user's information/data in a recurring fashion untill the user hasn't revoked access to your client id (represented by a Facebook app).
You get both a temporary token and a permanent token (which lasts for about 60 days at the time of writing this). You can get a new temporary token by using the permanent token every time you need to call the Facebook API (given the previous temporary token has expired) -- without bothering the user to grant permission again.
So, in short, for short term use, follow client-side authentication flow and for long term use follow server-side authentication (given you have a backend server of your own).

When adding Facebook integration to a web app, how do you handle OAuth token expiration and what user data should be saved?

I'm planning out adding Facebook integration to a web app I'm working on. For the most part, it's proceeding smoothly, but I am confused on the proper way to handle the OAuth token.
The sequence of events presented by Facebook here is:
Ask the user to authorize your application, which sends them to a Facebook window.
This will return an Authorization Code generated by Facebook
You then hit https://graph.facebook.com/oauth/access_token with your Authorization Code, which will give you a time-limited OAuth token.
Using the OAuth token, you can make requests to access the user's Facebook profile.
Facebook's documentation has the following to say about token expiration:
In addition to the access token (the access_token parameter), the response contains the number of seconds until the token expires (the expires parameter). Once the token expires, you will need to re-run the steps above to generate a new code and access_token, although if the user has already authorized your app, they will not be prompted to do so again. If your app needs an access token with an infinite expiry time (perhaps to take actions on the user's behalf after they are not using your app), you can request the offline_access permission.
When they say to re-run the steps above, what steps need to be re-run to get a new OAuth token? What data (Facebook UID, Authorization Code, OAuth token) does it make sense to save to my local database?
I would like to be able to have the user continue to interact with my site, and in response to certain user actions, I would like to be able to prompt to user if they want to post something to their Facebook wall.
The access token is time and session based and is unnecessary data to store and have no use after the user have closed the session.
The facebook uid is the only thing you need to identify the user.
Since the Facebook API sometimes is horrible slow you could store the username aswell.
But for identification, all you need is the uid.
The documentation that facebook provides has been updated since you asked this question. https://developers.facebook.com/docs/authentication/.