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'];
}
@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.