maringtr
maringtr

Reputation: 338

Cannot obtain page access token through an app that is granted the manage_pages permission

I'm trying to develop a PHP application that will let me make new posts on my Pages automatically, through a cronjob, while I am offline and not logged into Facebook at all. I'm aware that the offline_access permission has long been gone, but the Removal of offline_access permission article clearly states the following:

Scenario 5: Page Access Tokens

When a user grants an app the manage_pages permission, the app is able to obtain page access tokens for pages that the user administers by querying the [User ID]/accounts Graph API endpoint. With the migration enabled, when using a short-lived user access token to query this endpoint, the page access tokens obtained are short-lived as well.

Exchange the short-lived user access token for a long-lived access token using the endpoint and steps explained earlier. 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. This will also apply when querying with a non-expiring user access token obtained through the deprecated offline_access permission.

... which made me think that an automated PHP solution like what I had in mind was indeed possible to engineer. So I went ahead and created a new Application and granted the manage_pages permission, as well as the publish_actions permission.

However my code:

<?php
require_once("sdk/facebook.php");

$config = array();
$config['appId'] = MY_APP_ID;
$config['secret'] = MY_APP_SECRET;
$config['fileUpload'] = false; // optional

$facebook = new Facebook($config);

$accountID = MY_ACCOUNT_ID;
$pages = $facebook->api("/$accountID/accounts/");
var_dump($pages);
?>

...returns the following error:

Fatal error: Uncaught OAuthException: A user access token is required to request this resource.

What am I doing wrong?

Even more confusing - at the very same time, this piece of code here, posts a status update to my Wall without a problem (and I'm still not logged into Facebook or anything)

<?php
require_once("sdk/facebook.php");

$config = array();
$config['appId'] = MY_APP_ID;
$config['secret'] = MY_APP_SECRET;
$config['fileUpload'] = false; // optional

$token_url =    "https://graph.facebook.com/oauth/access_token?" .
                "client_id=" . $config['appId'] .
                "&client_secret=" . $config['secret'] .
                "&grant_type=client_credentials";
$app_token = str_replace('access_token=','',file_get_contents($token_url));


$facebook = new Facebook($config);

$args = array(
    'access_token'  => $app_token,
    'message'       => 'test post via app access token'
);
$accountID = MY_ACCOUNT_ID;
$post_id = $facebook->api("/$accountID/feed", "post", $args);
?>

...and if I do

$post_id = $facebook->api("/$myPageID/feed", "post", $args);

...instead, I get:

Fatal error: Uncaught OAuthException: (#200) The user hasn't authorized the application to perform this action

THE SOLUTION

With the kind help of Mr. Mohammed Alaghbari, I was able to make reasonable progress on this issue and eventually ended up coming to a solution.

As he suggested, I needed to generate a User Access Token first, issuing a request like this:

https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN

In order to retrieve the actual Page Access Token and post to the page. So I realized that as I log in through the Login Link generated by the PHP SDK, a USER_ACCESS_TOKEN is stored for me inside a $_SESSION variable. I took that token, issued a request to https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN, retrieved the PAGE_ACCESS_TOKEN and used it in order to successfully post a test message to my Page.

However, I then logged out and issued a session_destroy(); To my surprise, the minute I did that, my code started throwing the A user access token is required to request this resource. exception again. I was very frustrated.

Then, I decided to manually request https://graph.facebook.com/MY_ACCOUNT_ID/accounts/?MY_USER_ACCESS_TOKEN and see what happens. To my even bigger surprise - the GRAPH API accepted the USER_ACCESS_TOKEN and returned all valid Page Tokens. I was very frustrated why I was getting an exception in the SDK, but no errors when I issue a request directly to the GRAPH API, so I decided to start debugging base_facebook.php. The PHP SDK I'm using is Version 3.2.2.

After hours of searching, it turned out that this code located at line 899 of base_facebook.php throws the exception without a reason (sort of)

if (!isset($params['access_token'])) {
  $params['access_token'] = $this->getAccessToken();
}

When I commented the line $params['access_token'] = $this->getAccessToken(); out, my PHP SDK requests started returning valid tokens again.

Weird. I'm wondering if this is a bug in the PHP SDK, or a problem with my code. My final code looks roughly like this:

<?php
require_once("sdk/facebook.php");

$config = array();
$config['appId'] = MY_APP_ID;
$config['secret'] = MY_APP_SECRET;
$config['fileUpload'] = false; // optional

$facebook = new Facebook($config);

$token = MY_USER_TOKEN; // extracted from $_SESSION

$response = $facebook->api("/MY_ACCOUNT_ID/accounts/?access_token=$token");

// code that extracts the page token from $response goes here

$args = array(
    'access_token'  => MY_PAGE_TOKEN,
    'message'       => 'test post via app access token'
);

$post_id = $facebook->api("/MY_PAGE_ID/feed", "post", $args); // It works!!
?>

EDIT #2

After some further testing, it turned out that instead of commenting out line 899, you could just revise

$facebook->api("/MY_ACCOUNT_ID/accounts/?access_token=MY_ACCESS_TOKEN');

to

$facebook->api("/MY_ACCOUNT_ID/accounts/", 'get', array('access_token' => 'MY_ACCESS_TOKEN'));

Upvotes: 4

Views: 3457

Answers (2)

Mohammed Alaghbari
Mohammed Alaghbari

Reputation: 439

maringtr,

To interact with page you need to use Page Access Token (Check Access Token Types: Access Token Types)

Types Are: User Access Token, Page Access Token, App Access Token

Which can be generated with graph like this:

https://graph.facebook.com/me/accounts?access_token=USER_ACCESS_TOKEN

The above graph will give you a list of Pages you manage with there details (Page Name, ID, Access Token)

You can test the Page Access token to fetch Your Page Feeds with Graph (Replace Page_ID with your page id and PAGE_ACCESS_TOKEN with Page Access token generated from the above Graph )

https://graph.facebook.com/PAGE_ID/feed?access_token=PAGE_ACCESS_TOKEN&message=Testing

For more Information and Examples : Log In as Page

Regards,

Upvotes: 1

林果皞
林果皞

Reputation: 7833

Please grant status_update, as i've explained here why does posting to facebook page yield "user hasn't authorized the application"

Upvotes: 0

Related Questions