Php-graph-sdk: How can I do unlimited access token for page?

Created on 4 Mar 2017  路  13Comments  路  Source: facebookarchive/php-graph-sdk

Hello.

I read a lot of posts, facebook api (sdk) documentation and I cannot understand why access token of page is ends?
There is my code of yii2. What am I doing wrong? After few minutes facebook api saying "Graph returned an error: Error validating access token: Session has expired on Saturday, 04-Mar-17 10:00:00 PST. The current time is Saturday, 04-Mar-17 10:08:06 PST."
Why?

private $app_id = '170511.....';
private $app_secret = 'b20539e840....';

public function actionTest()
{
$fb = new \Facebook\Facebook([
'app_id' => $this->app_id,
'app_secret' => $this->app_secret,
'default_graph_version' => 'v2.8',
]);

$page_id = '157924....';
$page_access_token = 'EAAYOzBnVvBIBAJ86BSeD1....';

$linkData = [
    'link' => 'example.com',
    'message' => 'It works!',
];

try {
    // Returns a `Facebook\FacebookResponse` object
    $response = $fb->post("/{$page_id}/feed", $linkData, $page_access_token);
} catch(\Facebook\Exceptions\FacebookResponseException $e) {
    echo 'Graph returned an error: ' . $e->getMessage();
    exit;
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
    echo 'Facebook SDK returned an error: ' . $e->getMessage();
    exit;
}

$graphNode = $response->getGraphNode();

echo 'Posted with id: ' . $graphNode['id'];

}

All 13 comments

@portenko could you show the way how you've retrieved the page token?

@and800, of course.
I getting the user access token with permissions (manage_pages, publish_pages, publish_actions) on the main site (server side). After that I doing the access token is a long-lived. And after that I getting the page access token.

Step 1 (log in to facebook):

$fb = new \Facebook\Facebook([
    'app_id' => $model->app_id,
    'app_secret' => $model->app_secret,
    'default_graph_version' => 'v2.8',
]);
$helper = $fb->getRedirectLoginHelper();
$callback = "http://example.com/publisher/facebook?type=callback";
$permissions = ['manage_pages','publish_pages','publish_actions'];
$loginUrl = $helper->getLoginUrl($callback, $permissions);
<a href="<?= htmlspecialchars($loginUrl) ?>" class="btn btn-primary"><?= Yii::t('app', '袩芯谢褍褔懈褌褜 褌芯泻械薪') ?></a>

Step 2 (callback function and a long-lived access token):

$fb = new \Facebook\Facebook([
    'app_id' => $model->app_id,
    'app_secret' => $model->app_secret,
    'default_graph_version' => 'v2.8',
]);
$helper = $fb->getRedirectLoginHelper();
try {
    $accessToken = $helper->getAccessToken();
} catch (\Facebook\Exceptions\FacebookResponseException $e) {
    // When Graph returns an error
    Yii::$app->session->setFlash('error', 'Graph returned an error: ' . $e->getMessage());
    return $this->redirect('publisher/facebook');
} catch (\Facebook\Exceptions\FacebookSDKException $e) {
    // When validation fails or other local issues
    Yii::$app->session->setFlash('error', 'Facebook SDK returned an error: ' . $e->getMessage());
    return $this->redirect('publisher/facebook');
}

if (!isset($accessToken)) {
    if ($helper->getError())
    {
        Yii::$app->session->setFlash('error',
            "Error: " . $helper->getError() . "\n".
            "Error Code: " . $helper->getErrorCode() . "\n".
            "Error Reason: " . $helper->getErrorReason() . "\n".
            "Error Description: " . $helper->getErrorDescription() . "\n"
        );
        return $this->redirect('publisher/facebook');
    } else {
        Yii::$app->session->setFlash('error', 'Bad request');
        return $this->redirect('publisher/facebook');
    }
}
else
{
//            var_dump($accessToken->getValue());
    // The OAuth 2.0 client handler helps us manage access tokens
    $oAuth2Client = $fb->getOAuth2Client();

    // Get the access token metadata from /debug_token
    $tokenMetadata = $oAuth2Client->debugToken($accessToken);
//            var_dump($tokenMetadata);

    // Validation (these will throw FacebookSDKException's when they fail)
    $tokenMetadata->validateAppId($model->app_id);
    // If you know the user ID this access token belongs to, you can validate it here
    //$tokenMetadata->validateUserId('123');
    $tokenMetadata->validateExpiration();

    if (!$accessToken->isLongLived()) {
        // Exchanges a short-lived access token for a long-lived one
        try {
            $accessToken = $oAuth2Client->getLongLivedAccessToken($accessToken);
        } catch (\Facebook\Exceptions\FacebookSDKException $e) {
            Yii::$app->session->setFlash('error', 'Error getting long-lived access token: '. $helper->getMessage());
            return $this->redirect('publisher/facebook');
            //exit;
        }
        //var_dump($accessToken->getValue());
    }
    $model->access_token = $accessToken->getValue();
}

Step 3 (page access token):

{
    $page_access_token = $fb->get("/{$model->page_id}/?fields=access_token", $model->access_token);
    $_decoded_access_token = $page_access_token->getDecodedBody();
    $model->page_access_token =  $_decoded_access_token['access_token'];
//  var_dump($page_access_token->getDecodedBody()); exit();
} catch(\Facebook\Exceptions\FacebookSDKException $e) {
    Yii::$app->session->setFlash('error', 'Facebook SDK returned an error: ' . $e->getMessage());
    return $this->redirect('publisher/facebook');
}

Is the page access token a long-lived (how many days or is it unlimited expires)?

@portenko hmm, I was solving the same task today and I wrote practically the same code to build long-lived page token. It worked well for me (but I tested it only a few minutes since token had been generated). Docs say that resulting page token should be immortal.

There also exists such a tool as Token Debugger: https://developers.facebook.com/tools/debug/accesstoken/
I put my token there and it showed me Expires: never. You should definitely try it to get more info about this bug.

I will check tomorrow and white there if my token is still alive

It's my second attempt to create a long-lived token. It's working yet.

Same thing. Can't understand how to get never expires toke. I always get two-month-token.
Send request to
https://graph.facebook.com/v2.8/{valid_page_id}/accounts?access_token={valid_long_lived_token}
or
https://graph.facebook.com/v2.8/me/accounts?access_token={valid_long_lived_token}
But I get only {"data":[]}

In order to obtain a Page access token that never expires, you need to use a long-lived User access token to obtain it. :)

SammyK, yeah, I read this already 50 times or more, and spend hours trying to get this unexpired token.
Already get short-lived token.
Then get long-live (2 month) token. _manage_pages_ included.

$unexpiredAccessToken = $oAuth2Client->getLongLivedAccessToken($longLivedAccessToken);
But unexpiredAccessToken is still two month.

Tokens that never expire are only available for Page access tokens. User access tokens will always expire - even the long-lived ones.

So... I need make get request like this?

$fb = Facebook(['app_id'=> id, 'app_secret' => secret, 'default_graph_version' => 'v2.8']);
$result = $fb->get('{page_id}?fields=access_token', $access_token);

page_id - it's group ID?
$access_token - long-lived User access token?

@Stepanov117 yes, just try it
Then you get the token string using $result->getDecodedBody()['access_token']

@and800 oh...

Notice: Undefined offset: 1 in php-graph-sdk-5.0.0/Http/GraphRawResponse.php on line 108

Fatal error: Uncaught TypeError: Argument 4 passed to Facebook\FacebookResponse::__construct() must be of the type array, null given, called in php-graph-sdk-5.0.0/FacebookClient.php on line 224 and defined in php-graph-sdk-5.0.0/FacebookResponse.php:75 Stack trace: #0 php-graph-sdk-5.0.0/FacebookClient.php(224): Facebook\FacebookResponse->__construct(Object(Facebook\FacebookRequest), 'r":{"message":"...', 0, NULL) #1 php-graph-sdk-5.0.0/Facebook.php(504): Facebook\FacebookClient->sendRequest(Object(Facebook\FacebookRequest)) #2 php-graph-sdk-5.0.0/Facebook.php(373): Facebook\Facebook->sendRequest('GET', '/18703008032493...', Array, Object(Facebook\Authentication\AccessToken), NULL, 'v2.8') #3 fb-callback.php(22): Facebook\Facebook->get('/18703008032493...', Object(Facebook\Authentication\AccessToken)) #4 {main} thrown in php-graph-sdk-5.0.0/FacebookResponse.php on line 75

@Stepanov117 lol, you have broken the sdk:)
it seems reasonable for me to create a separate issue with this error

@and800 solution - update to 5.4.4 (error in 5.0.0).
But doesn't work:
$result = $fb->get('{page_id}?fields=access_token', $access_token);

Fatal error: Uncaught Facebook\Exceptions\FacebookAuthenticationException: Syntax error "Expected end of string instead of "?"." at character 4: acce??ss_token in /php-graph-sdk-5.4.4/Exceptions/FacebookResponseException.php:131 Stack trace: #0 /php-graph-sdk-5.4.4/FacebookResponse.php(210): Facebook\Exceptions\FacebookResponseException::create(Object(Facebook\FacebookResponse)) #1 /php-graph-sdk-5.4.4/FacebookResponse.php(255): Facebook\FacebookResponse->makeException() #2 /php-graph-sdk-5.4.4/FacebookResponse.php(82): Facebook\FacebookResponse->decodeBody() #3 /php-graph-sdk-5.4.4/FacebookClient.php(224): Facebook\FacebookResponse->__construct(Object(Facebook\FacebookRequest), '{"error":{"mess...', 400, Array) #4 /php-graph-sdk-5.4.4/Facebook.php(469): Facebook\FacebookClient->sendRequest(Object(Facebook\FacebookRequest)) #5 /home/s-stepanov/www in /php-graph-sdk-5.4.4/Exceptions/FacebookResponseException.php on line 131

In documentation said: use _/me/accounts_
So $fb->get('me/accounts', $access_token); return exactly same token.

Was this page helpful?
0 / 5 - 0 ratings