Getting the right access token - facebook

I'd like my application could read the posts from a group.
To do it, I got the access token in the following url:
https://developers.facebook.com/tools/explorer?method=GET&path=404425692946289%2Ffeed
and I call que following url:
https://graph.facebook.com/404425692946289/feed?access_token=debug_token_generated_from_above_url
And it works like a charm.
But I can't get any results when I call the url above with the token that was generated using my application id and secret:
https://graph.facebook.com/oauth/access_token?client_id=myid&client_secret=mysecret&grant_type=client_credentials <--- The token generated by this url does not work! =(
I am receiving the following data:
{
"data": [
]
}
I supposedly have the read_stream extended permission configured on my application.

One way to check for your self what permissions the token in the API explorer has, is to call /me/permissions
In addition grant_type=client_credentials is for app tokens. You need a user token most likely. Please review the documentation where you got that information from.

Related

Facebook access token extending - "The access token does not belong to application xxx"

I went to https://developers.facebook.com/tools/explorer?method=GET, set up there ID of my Facebook page, set up there the correct permission for posting statuses on my FB timeline and generated access token.
Then I wanted to extend this short-live token on the long-term (60 days long valid token). So I did following - I put this URL to the browser:
https://graph.facebook.com/oauth/access_token?client_id=APP_ID_OF_MY_FB_APP&client_secret=SECRET_ID_OF_MY_APP&grant_type=fb_exchange_token&fb_exchange_token=GENERATED_ACCESS_TOKEN_FROM_THE_FIRST_STEP
and in the browser I saw this error message:
{
"error": {
"message": "The access token does not belong to application APP_ID_OF_MY_FB_APP",
"type": "OAuthException",
"code": 1
}
}
Which is weird, because the APP_ID of my Facebook app is correct, I've tried to post on the wall of the Facebook page and it was working.
But when I try to get extended access token, I am getting the error above.
What's wrong with the access?
Thank you
This almost certainly means what the error says, which is that GENERATED_ACCESS_TOKEN_FROM_THE_FIRST_STEP is not actually from the app ID that you're using in the APP_ID_OF_MY_FB_APP parameter
Check the access token you're trying to extend in Facebook's Debug Tooland ensure it was actually generated for your app
Your AppID param is not the same to the AppID in developers.facebook.com

Posting on user's timeline on the behalf of the user

I created and APP on the Facebook.
Now I am trying to post a comment on the user's timeline using the Graph API but I cannot undestand what I need to do.
I already authorized the Application (I authorized this permissions: 'user_status,publish_stream,user_photos,email').
If I look on my profile -> privacy I can see that the APP can:
This app can: Post on your behalf
This app may post on your behalf, including status updates, photos and more.
Last data access:
Basic InformationToday
See details ยท Learn more
Posts on your behalf:
Who can see posts this app makes for you on your Facebook timeline?
Public
Notifications:
When to notify you?
The app sends you a notification
So this part seems OK.
On my application I do the following to try to post somenthing on my timeline (I need to post it when I am off line).
1) GET : https://graph.facebook.com/oauth/access_token?client_id=APPID&client_secret=*APP_SECRET*&grant_type=client_credentials
RESPONSE:
access_token = 422828347771671|UdQELQIf0N7krF4JUo7VwtPLTkk
2) GET: https://graph.facebook.com/search?q=myemail&type=user
RESPONSE:
_"error":_{
______"message":_"A_user_access_token_is_required_to_request_this_resource_",
______"type":_"OAuthException",
______"code":_102
___}
But reading the documentation (https://developers.facebook.com/docs/reference/api/#searching) it seems that this request does not need any kind of access token.
I also tried to add the access token, but the result is still the same.
3) I know my facebookid so I tried to use it directly:
POST: https://graph.facebook.com/100001139132403/feed
ARGUMENT:
access_token=422828347771671|UdQELQIf0N7krF4JUo7VwtPLTkk,
message=Hello
RESPONSE:
"error": {
"message": "(#200) This API call requires a valid app_id.",
"type": "OAuthException",
"code": 200
}
}
So I tried to add client_id=APPID and app_id=APPID, I tried to put one, the other and also both arguments as GET or POST but nothing changed.
I checked the APPId ad it is correct.
Do someone have any idea?
Thank you!
You cant simply generate a user access_token by querying to a URL. What you did gives the App access token and as the error say, you are trying to do something, that needs user access_token.
Refer and implement this : https://developers.facebook.com/docs/howtos/login/server-side-login/
And use that access_token for the rest of the processes.

Get application id from user access token (or verify the source application for a token)

I found this question, which has an answer, but facebook changed the token format since then, now it is something like:
AAACEdEose0cBACgUMGMCRi9qVbqO3u7mdATQzg[more funny letters]ig8b3uss9WrhGZBYjr20rnJu263BAZDZD
In short, you cannot infer anything from it.
I also found the access token debugger, which shows the information I am looking for if you paste a token in, which is nice, but does not help me do it programmatically.
Point is, if someone gets a token for a user, he can use it to access the graph, which is what I do in my application - I want to be sure that people are forwarding the token that was issued to them by my application, and not another.
My application flow is:
Get access token from facebook (nothing special, in the way it is described in here , Server-side Flow. (also iPhone and android and used, but they have similar flows if I recall correctly))
[device] <-> [facebook]
With that access token, the device will access my application server with the token
[device] <-> [Jonathan's application]
At my server I attach the access token to the user and use that to give permissions to that user in my application. (using the facebook connect to authenticate users)
My application is secured, and the access done is also authenticated regardless of facebook, BUT! in this flow, the a weak link I identified is that I cannot authenticate for sure that the access token I got was signed for my application - I do not like it because I cache the tokens for offline use, I want to be 100% sure they are for my application, with my permissions.
So what will be the (best) way to authenticate that the token I got is related to my application (for relation to user, I use the token to access /me and see which user this token is for)
I do not need to decrypt the token (i guess its some sort of AES), I am just looking for an endpoint that will tell me the token matched my application id.
(EDIT: Using the C# SDK, if it matters.. But a graph/rest call to give that info is just as good as well :) )
https://graph.facebook.com/app/?access_token=[user_access_token]
This will return the app this token was generated for, you can compare that against your app's id.
The official graph endpoint for inspecting access tokens is:
GET graph.facebook.com/debug_token?
input_token=[user_access_token]&
access_token=[app_token_or_admin_token]
Example response:
{
"data": {
"app_id": 138483919580948,
"application": "Social Cafe",
"expires_at": 1352419328,
"is_valid": true,
"issued_at": 1347235328,
"metadata": {
"sso": "iphone-safari"
},
"scopes": [
"email",
"publish_actions"
],
"user_id": 1207059
}
}
app_token_or_admin_token can be obtained using the Graph API call:
GET graph.facebook.com/oauth/access_token?
client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials
The debug_token endpoint will fail if that user_access_token doesn't belong to the app that generated the app_token_or_admin_token.
Relevant facebook documentation:
Inspecting access tokens:
https://developers.facebook.com/docs/facebook-login/login-flow-for-web-no-jssdk/#checktoken
App Tokens:
https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens
A documented way to ensure this is to use appsecret_proof.
GET graph.facebook.com/v2.5/me?access_token=[TOKEN]&appsecret_proof=[PROOF]
This verifies not only that it is a valid token, but also that the token belongs to the app. It also gets you user data in one go.
You can derive PROOF above in C# using this (from here):
public static string ComputeHmacSha256Hash(string valueToHash, string key)
{
byte[] keyBytes = Encoding.ASCII.GetBytes(key);
byte[] valueBytes = Encoding.ASCII.GetBytes(valueToHash);
byte[] tokenBytes = new HMACSHA256(keyBytes).ComputeHash(valueBytes);
valueBytes = null;
keyBytes = null;
StringBuilder token = new StringBuilder();
foreach (byte b in tokenBytes)
{
token.AppendFormat("{0:x2}", b);
}
tokenBytes = null;
return token.ToString();
}
ComputeHmacSha256Hash(accessToken, appSecret);
Why not to use official way of doing things? Here's the request from FB's own video about security.
Request:
https://graph.facebook.com/debug_token?input_token={token-to-check}&access_token={app_id}|{app_secret}
Response:
"data": { "app_id": {token-app-id}, "user_id": {token-user-id}, ... }
Link to an official video: https://www.facebook.com/FacebookforDevelopers/videos/10152795636318553/
I made a screenshot so that time is visible, and you can find more info if you are interested.

Facebook access token server-side validation for iPhone app

I'm developing iPhone application, that is based on communication with server, and I want to use Facebook authentication mechanisms.
Basically, I think it should work like this:
In my iPhone app, user logs in to Facebook, using his email and password.
User allows access to his data for related Facebook application.
My iPhone app receives access token, after successful log in.
In further communication with my server, my iPhone application should use the received Facebook access token (for example: in queries).
When my server receives some query from iPhone app, with access token, it should ask Facebook that this token is valid (and for who), and if yes, server should assume that user is authenticated with Facebook.
My question is: how the server should ask Facebook if given access token is valid? I think I should somehow check if the token is valid for my Facebook app.
I've tried many Facebook queries to graph API, that I've found, but nothing worked as I expected. Can you provide me some example?
Here's a two step process you can use to validate that a user access token belongs to your App:
1) Generate an App Access token
(https://developers.facebook.com/docs/howtos/login/login-as-app/)
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID
&client_secret=YOUR_APP_SECRET
&grant_type=client_credentials
2) Debug the User Access token
(https://developers.facebook.com/docs/howtos/login/debugging-access-tokens/)
https://graph.facebook.com/debug_token?
input_token=INPUT_TOKEN
&access_token=ACCESS_TOKEN
Where INPUT_TOKEN is the user access token you want to verify, and ACCESS_TOKEN is your app's token that you got from step 1.
The debug endpoint basically dumps all information about a token, so it'll respond with something like this:
{
data: {
app_id: YOUR_APP_ID,
is_valid: true,
metadata: {
sso: "iphone-safari"
},
application: YOUR_APP_NAMESPACE,
user_id: USER_ID,
issued_at: 1366236791,
expires_at: 1371420791,
scopes: [ ]
}
}
If that token isn't from "your app" then it will return an error response.
Update: this answer seems insecure since it doesn't validate the token
first as belonging to your app, see the comments, original answer as
follows:
I assume that you already have the access token in hand. In such a case the simplest way to validate an access token is to issue the following request
https://graph.facebook.com/me?fields=id&access_token=#accesstoken
Here replace #accesstoken with the access token you have. I will breakdown the url and will explain each.
We are issuing a graph api request here which will return the Facebook User Id of the owner of the access token as a JSON string. The keyword 'me' represents the currently logged in user or the owner of the access token. For this request access token is a mandatory parameter.
If the provided access token is not valid or expired Facebook will just return an error message of some sort.
For a valid access token the result will somehow look like this
{
"id": "ID_VALUE"
}
Another solution would be to use https://graph.facebook.com/app/?access_token=[user_access_token] as described by Get application id from user access token (or verify the source application for a token).
This appears to be an undocumented feature, but returns JSON containing the id of the app the token was generated for. If the token wasn't for your app, it returns a 400.
In the latest version of facebook (2.2) you can do it this way:
https://developers.facebook.com/docs/graph-api/reference/v2.2/debug_token
Sample output:
{
"data": {
"app_id": "THE APP ID",
"application": "APP NAME",
"expires_at": 1427245200,
"is_valid": true,
"scopes": [
"public_profile",
"basic_info",
"read_stream",
"email",
"publish_actions",
"read_friendlists",
"user_birthday",
"user_hometown",
"user_location",
"user_likes",
"user_photos",
"user_videos",
"user_friends",
"user_posts"
],
"user_id": "THE USER ID"
}
}
private function facebookRequestMe($access_token)
{
include_once "facebook.php";
$facebook = new Facebook(array(
"appId" => "your_application_id",
"secret" => "your_application_secret"
));
$facebook->setAccessToken($access_token);
return $facebook->api("/me", "GET");
}
You can download the Facebook SDK for PHP from GitHub.
If a user has passed you a Facebook UID that they claim is theirs and you want to check if it's legit, this is a Python function that will verify it against their access token (an implementation of Robin Jome's answer):
def verify_facebook_id(id, access_token):
import requests
import simplejson
params = {'fields': 'id', 'access_token': access_token}
text = requests.get("https://graph.facebook.com/me", params=params).text
json = simplejson.loads(text)
response_id = json["id"]
return response_id == id
This is the only secure method to verify user token using just one request:
https://graph.facebook.com/debug_token?input_token={token-to-inspect}&access_token={app_id}|{app_secret}
Note that a sign "|" in the above URL isn't used as OR but as separator and must be there after fill the other fields.
The response will be JSON looking like that:
{
data: {
app_id: {app_id},
application: {app_name},
expires_at: {some_number},
is_valid: {true|false}
scopes: {array_of_permissions},
user_id: {user_id}
}
}
Reference: https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens
(above method is mentioned at the bottom of this section)
Along with an access token Facebook also sends an "expires_in" parameter, which is an offset value. Use that to compute for when the access token will expire as an NSDate. Then when you need to do a request compare the current date with the expiration date.
Also try to inspect the status codes and response strings Facebook sends back.

facebook auth code becomes invalidate after hours?

I've a simple application in facebook. To change user's facebook status, I need to get code via
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID&redirect_uri=YOUR_URL
Then I use that code to generate a auth token. With the token I can update user's stauts. It works for one or two days. After that, when trying to generate auth token with code, I got an error like:
{
"error":{
"type":"OAuthException",
"message":"Code was invalid or expired."
}
}
So how long can a code be validate?
There is a way to get an infinite token from facebook. Use the offline_access parameter in requesting permissions, and you will never lose the token.
You just need to grant the publish_stream the first time and get the user id, after that no need to go through this process again and you can just use:
curl -F 'message=Hello World.' \
https://graph.facebook.com/USERID/feed
or in PHP-SDK:
$facebook->api("/USER_ID/feed", "post", array("message"=>"Hello World!"));