How do I get a page Access Token that does not expire? - facebook-graph-api

I would like to know if it is possible to have an access token that never expires for post to my page
Now I get the access token with:
https://graph.facebook.com/me/accounts
I have publish_stream and manage_pages permission, but using the Access Token Debugger I see that the token expires in about 1 hour. Is there a way to never expires?

See facebook developers:
By using a long-lived user access token, querying the [User
ID]/accounts endpoint will now provide page access tokens that do not
expire for pages that a user manages.
So, you have to exchange your initial shortlived token for a longlived token with a server side call:
https://graph.facebook.com/oauth/access_token?
client_id=APP_ID& client_secret=APP_SECRET& grant_type=fb_exchange_token& fb_exchange_token=EXISTING_ACCESS_TOKEN
And then query me/accounts with that longlived token. Definitly works for us, i.e. the debugger shows: 'Expires: Never'
edit - our process
So, what we do is:
first client side authentication with our app where we get a "code" back after the user accepts the requested permissions and connects his account with our app
https://www.facebook.com/dialog/oauth?
client_id=YOUR_APP_ID &redirect_uri=YOUR_REDIRECT_URI &scope=COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES &response_type=code
Now in our server application we use server side authentication to exchange code for access token:
https://graph.facebook.com/oauth/access_token?
client_id=YOUR_APP_ID &redirect_uri=YOUR_REDIRECT_URI &client_secret=YOUR_APP_SECRET &code=CODE_GENERATED_BY_FACEBOOK
With this access_token we do the server side exchange as described above
Now we request me/accounts and the resulting access_token is always valid
Hope that helps

I've simplified Pete's answer a bit and added the step to get a non-expiring page access token:
access the following URL and note the returned access token within the browser's address bar:
https://www.facebook.com/dialog/oauth?client_id=APP_ID&redirect_uri=REDIRECT_URI&scope=manage_pages,publish_stream&response_type=token
access the following URL and within the returned data find the desired page's name and note the access token:
https://graph.facebook.com/me/accounts?access_token=ACCESS_TOKEN_RETURNED_FROM_STEP_1
access the following URL and note the returned access token:
https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=PAGES_ACCESS_TOKEN_FROM_STEP_2
use the Access Token Debugger to ensure your access token's profile ID matches the desired page's ID and it never expires

There is a MUCH easier way to do this as of 2016 :)
Go to https://developers.facebook.com/tools/explorer
Select your app from the dropdown on the top right hand
side
Click “Get Access Token” button just below the application dropdown
on the right hand side
In the dropdown select the page you want to get a access token for.
If you don’t see your pages listed then you’ll need to make sure
you’re set with the admin role for the page. Also you may have to
click “Get Page Access Token” in the dropdown, after which then your
pages will show in the dropdown next time you click the “Get Access
Token” button.
Click the blue exclamation point icon in the “Access token” input field
Click the “Open in Access Token Tool” button on the
bottom right of the popup
Click the “Extend Access Token” button to get an token that never
expires
Original info from this article: https://www.rocketmarketinginc.com/blog/get-never-expiring-facebook-page-access-token/

Ok so it took about a week of research but here is my solution.
in the https://developers.facebook.com/tools/explorer/ make sure that you have manage_page as part of your access_token. after that use this code with your app id, secret, and redirect:
<?php
app_id = "APP_ID";
$app_secret = "APP_SECERET";
$post_login_url = "REDIRECT_URL";
$code = $_REQUEST['code'];
//Obtain the access_token with publish_stream permission
if(empty($code)){
$dialog_url= "http://www.facebook.com/dialog/oauth?"
. "client_id=" . $app_id
. "&redirect_uri=" . urlencode( $post_login_url)
. "&COMMA_SEPARATED_LIST_OF_PERMISSION_NAMES";
echo("<script>top.location.href='" . $dialog_url
. "'</script>");
}
else {
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
. "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$access_token = $params['access_token'];
echo 'access token: ' . $access_token.'<br>';
if($access_token){
$token_url="https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id
. "&redirect_uri=". urlencode($post_login_url)
. "&client_secret=" . $app_secret
.'&grant_type=fb_exchange_token'
. "&fb_exchange_token=" . $access_token;
$response = file_get_contents($token_url);
$access_token = $params['access_token'];
echo 'new access token: '.$access_token;
}
}*/
?>
After that copy the 'new access token' and go back to https://developers.facebook.com/tools/explorer/ When you get there past in your new access token into the the access token field.
Then click submit. After that in the node you will see a +____ click on this and scroll down to the accounts and click that. find the page that you need the access token for and copy and paste it into the access key field. click debug and you will see that it will never expire. save that token it will stay valid as long as you do not reset your apps secret.

You can use following api from facebook to refresh token life to 60 days and just when the token is about to expire, call the same api again with-in 60 days to refresh its life back to 60 days from that point of time
Token expire is present in expires parameter and its value is in seconds
Replace CLIENT_ID and CLIENT_SECRET with their actual value
https://graph.facebook.com/oauth/access_token?client_id=&client_secret=&grant_type=fb_exchange_token&fb_exchange_token=
in ACCESS_TOKEN, put the actual token value without appending "access_token="

Related

Is it even possible to post to a facebook page as a admin [duplicate]

I know how to make a post to a Facebook page via the API using PHP SDK, that is done like this:
$facebook->api('/xxxxxxxxxxx/feed', 'post', array('message'=> 'Hello world!', 'cb' => ''));
Where xxxxxxxxxxx is page id ;)
But doing that, I post to that page as me, Jamie, and not as the Page itself (admin).
So how do I post as Admin/Page instead of myself?
Thanks you for your time!
ANSWER (for lazy people):
First of all you need to make sure you have access to manage pages for user, ex:
<fb:login-button autologoutlink="true" perms="manage_pages"></fb:login-button>
Now you also gets a special token for every page user have access to once you get them.
PHP SDK Example:
//Get pages user id admin for
$fb_accounts = $facebook->api('/me/accounts');
//$fb_accounts is now an array
//holding all data on the pages user is admin for,
//we are interested in access_token
//We save the token for one of the pages into a variable
$access_token = $fb_accounts['data'][0]['access_token'];
//We can now update a Page as Admin
$facebook->api('/PAGE_ID/feed', 'post', array('message'=> 'Hello!', 'access_token' => $access_token, 'cb' => ''));
Check out this note regarding your question: http://developers.facebook.com/docs/api > Authorization > Page impersonation.
Long story short, you need the manage_pages extended permission.
And btw, have you checked this first ?

Why is the accesstoken not set by PFFacebookUtils logInInBackgroundWithReadPermissions method?

For reference: I am using the latest Facebook IOS SDK v4 and the latest Parse v1.7.4 and ParseFacebookUtilsV4 SDK.
So I am using PFFacebookUtils loginInBackgroundWithReadPermissions:block: method to have the user login with Facebook credentials and create a PFUser with those credentials.
And then proceeded to make a facebook graph request with FBSDKGraphRequest which from what i read, assumes a valid token has been set (there is no passing of a token parameter to it).
But the facebook graph request failed, and in tracing the issue, I noticed that the "access token" is never set by the loginInBackgroudnWithReadPermissions method. What this method only does is to create a PFUser and a Session instance in Parse, and store there the session token string, but it does not set the currentAccessToken . When I do a [[FBSDKAccessToken currentAccessToken] tokenString] call within the block, I get (null). But if I read the "token string" from the PFSession class I get the "token string" store in the Session class instance in Parse.
See the code below:
- (IBAction)fbLoginAction:(id)sender {
// Set permissions required from the facebook user account
NSArray *permissionsArray = #[ #"email", #"user_friends"];
// Login PFUser using Facebook
[PFFacebookUtils logInInBackgroundWithReadPermissions:permissionsArray block:^(PFUser *user, NSError *error) {
if (!user) {
NSLog(#"Uh oh. The user cancelled the Facebook login.");
} else if (user.isNew) {
NSLog(#"User signed up and logged in through Facebook!");
// Check if the current token has been set
NSLog(#"self.myCurrentToken string = %#", [[FBSDKAccessToken currentAccessToken] tokenString]); // returns (null)
// Get the token string from the PFSession
[PFSession getCurrentSessionInBackgroundWithBlock:^(PFSession *session, NSError *error) {
NSString *tokenString = session.sessionToken;
NSLog(#"Session token = %#", tokenString);
}];
}
And here is the debug console output
So I am not sure what is happening.
IF the PFSession token is set to something shouldn't the FBSDKAccessToken currentAccessToken not be returning this same PFsession token?
And if I were to set the accessToken manually, how can I convert the tokenstring that is stored in Parse to an FBSDKAccessToken instance? There seems to be no method to do this?
thanks
This is happening because you need to add the following code to the bottom of AppDelegate didFinishLaunchingWithOptions :
return [[FBSDKApplicationDelegate sharedInstance] application:application
didFinishLaunchingWithOptions:launchOptions];
By adding the code, your currentAccessToken will no longer be nil and you can make requests to FB right away.
FYI, I was able to discover the acccessToken was nil because I got the following error every time I tried to use FBSDKGraphRequest. So if anyone else gets the error below, make sure your accessToken is not nil even after you log in!
{"error":{"message":"An active access token must be used to query information about the current user.","type":"OAuthException","code":2500}}
#jhk:
Yes. I got an explanation from Facebook support. Login in through Parse is a two step process. First step, is the authorization step, where the user authenticates with Facebook. It switches to Facebook app, and the app receives Facebook access token when it completes successfully. And the second step is , the app authenticates with Parse (i.e your app) using the Facebook token. If it matches existing user/session, you are logged in successfully. However, I was deleting the PFSession manually from the parse backend, while testing every single time I tried to login, so that invalidated the session stored in the backend, and after the 1st step, when the app gets authorized and gets the accesstoken, the system realizes that the local session doesn't match the parsed stored session and invalidated the accesstoken, it sets it to nil. That is why I am seeing the token being set to nil.

Facebook access tokens expire resulting in my app not working

I have developed an app so that users can upload images to a page's album. I do not want users to have to authorize and so I used the access token from the app to upload the images for them. This works fine if the admin is logged in and the access token hasn't expired - it only seems to last for a couple hours. I have looked through stackoverflow and facebook and tried many different things and nothing seems to work. Here is some of the code I am using:
try {
$facebook->setAccessToken("APP_ACCESS_TOKEN_FROM_GRAPH_API_TOOL");
$token_url="https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=fb_exchange_token&fb_exchange_token=".$facebook->getAccessToken();
$page_id = 'PAGE_ID';
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
$page_info['access_token'] = $params['access_token'];
$page_info = $facebook->api("/".$page_id."?fields=access_token");
if( !empty($page_info['access_token']) ) {
$photo_details['access_token'] = $page_info['access_token'];
$upload_photo = $facebook->api('/'.$page_id.'/photos', 'post', $photo_details);
Am I dreaming? Is this possible and I just screwed up the code? Any help would be much appreciated even just to point me in the right direction...
Currently, your code uses your own Access Token, not the App Access token.
To get the app access token, you need to make a get request to https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=client_credentials as documented at https://developers.facebook.com/docs/technical-guides/opengraph/publishing-with-app-token/
in your implementation, and assuming that APP_SECRET and APP_ID are defined as constants, you'd get the app access token through :
$appAccessToken = str_replace("access_token=","",$facebook->api("https://graph.facebook.com/oauth/access_token?client_id=APP_ID&client_secret=APP_SECRET&grant_type=client_credentials"));
$facebook->setAccessToken($appAccessToken);

PHP facebook graphapi getting "An active access token must be used to query information about the current user."

I have this PHP code that i need help with
here is what i have
$facebook = new Facebook(array(
'appId' => FB_APP_ID,
'secret' => FB_APP_SECRET,
'cookies' => 'true'
));
$FBuser = $facebook->getUser();
$token_url = "https://graph.facebook.com/oauth/access_token?" .
"client_id=" . FB_APP_ID .
"&client_secret=" . FB_APP_SECRET .
"&grant_type=client_credentials";
So far so good.. but then i try
$permissions = $facebook->api("/me/permissions");
And i get the error
"An active access token must be used to query information about the current user."
I know the user has already installed my app. I must be missing something simple??
Thanks
Randy
This:
$token_url = "https://graph.facebook.com/oauth/access_token?" .
"client_id=" . FB_APP_ID .
"&client_secret=" . FB_APP_SECRET .
"&grant_type=client_credentials";
Simply gets an access token for the APP. There is no user attached to this. Read this documentation about getting a user's login url. Then, the facebook SDK you have at that redirect_uri will finish the job for you, and get you an access_token. From there you just need to call $permissions = $facebook->api("/me/permissions"); and it should work just fine.
To be sure, after you get that access_token in your current script, run it in the debugger to ensure a user_id is tied to it.

Facebook: retrieving Request object (from request_id) before authorization using JS SDK

When a user comes into my app via an apprequest, Facebook appends a request_id to the URL.
I am trying to access this object before the user authorizes my application. When I try to make the api call:
FB.api('/'+requestId, function(response){ console.log(response); });
it returns the following:
error: Object
message: "An access token is required to request this resource."
But I should have access since it was my app that sent the request in the first place!
I did some digging, and I noticed that on the PHP side, it will use the user_access_token if available, and the app_access_token otherwise.
Is this a security limitation (i.e: cannot expose the app_access_token on the client side) or am I doing something wrong?
Any insight would be helpful. Thanks!
when you make a request to /{user_id}/apprequests you have to have authorized the user already...
Since the request was created by your application - only your application can manage -ie delete or read requests that were sent. Essentially, before the user authorizes you app he/she is anonymous to your application - therefore it would not be possible to read that users requests because you "dont know" who they are...
Hope this helps...
The following blog posts describes how to interact with requests and should hopefully answer your questions.
http://developers.facebook.com/blog/post/464
<?php
$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';
$token_url = "https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $app_id .
"&client_secret=" . $app_secret .
"&grant_type=client_credentials";
$access_token = file_get_contents($token_url);
$signed_request = $_REQUEST["signed_request"];
list($encoded_sig, $payload) = explode('.', $signed_request, 2);
$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);
$user_id = $data["user_id"];
//Get all app requests for user
$request_url ="https://graph.facebook.com/" .
$user_id . "/apprequests?" .
$access_token;
$requests = file_get_contents($request_url);
//Print all outstanding app requests
echo '<pre>';
print_r($requests);
echo '</pre>';
//Process and delete app requests
$data = json_decode($requests);
foreach($data->data as $item) {
$id = $item->id;
$delete_url = "https://graph.facebook.com/" .
$id . "?" . $access_token . "&method=delete";
$result = file_get_contents($delete_url);
echo("Requests deleted? " . $result);
}
?>
You have access to the app generated requests as the user follows the request via your app token but you need the user token to access the rest of the users requests.