使用 PHP SDK 访问 Facebook Graph API 的代码在重新加载页面时不起作用
Code to access Facebook Graph API with PHP SDK not working when reloading page
我正在编写一些代码来获取由 Facebook 用户管理的 Facebook 页面,使用 Facebook Graph API。我的代码请求用户的授权并获得一个令牌,使它能够获取此信息,然后将其存储在会话中。问题是,如果我重新加载页面,存储的令牌将被取消设置,我将无法获得由 Facebook 用户管理的 Facebook 页面。
当页面重新加载时,令牌显然已通过 'validateExpiration()' 函数撤销。
我错过了什么?
这是我的代码:
session_start();
// Load the Facebook PHP SDK
require_once __DIR__ . '/facebook-sdk-v5/autoload.php';
define('APP_ID', 'xxxxxxxxxxxxxxxx');
define('APP_SECRET', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
$fb = new Facebook\Facebook([
'app_id' => APP_ID,
'app_secret' => APP_SECRET,
'default_graph_version' => 'v2.7'
]);
if(isset($_SESSION['fb_access_token'])) {
echo '$_SESSION["fb_access_token"] = ' . $_SESSION['fb_access_token'] . '<br>';
// Create a new AccessToken object from its string code. Needed?
$accessToken = new Facebook\Authentication\AccessToken($_SESSION['fb_access_token']);
$expirationDate = $accessToken->getExpiresAt();
echo 'Token expires at: ' . var_dump($expirationDate) . '<br>'; // Returns null!
// verifies the validity and expiration of the token
$oAuth2Client = $fb->getOAuth2Client();
$tokenMetadata = $oAuth2Client->debugToken($accessToken);
try {
echo 'Validating token<br>';
$tokenMetadata->validateAppId(APP_ID);
$tokenMetadata->validateExpiration(); // This apparently throws an exception
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'I will now unset the token<br>';
unset($accessToken);
unset($_SESSION['fb_access_token']);
}
if(!isset($accessToken)){
echo 'Token not set!';
exit;
}
// Check permissions
if (isset($accessToken)) {
$response = $fb->get('/me/permissions', $accessToken);
$permissions = $response->getDecodedBody();
echo 'Permissions: ';
print_r($permissions);
$permissions_list = [];
foreach($permissions['data'] as $perm) {
if($perm['status'] == 'granted') {
$permissions_list[] = $perm['permission'];
}
}
echo 'Permissions list: ';
print_r($permissions_list);
if(!in_array('pages_show_list', $permissions_list)) {
echo 'I will now unset the token<br>';
unset($accessToken);
unset($_SESSION['fb_access_token']);
}
}
} else {
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} 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;
}
}
if(isset($accessToken)) {
// Logged in!
// Save the string code of the AccessToken to re-create it later
$_SESSION['fb_access_token'] = (string) $accessToken;
echo '$_SESSION["fb_access_token"] = ' . $_SESSION['fb_access_token'] . '<br>';
try {
$response = $fb->get('/me/accounts', $accessToken);
$data = $response->getDecodedBody();
echo '<pre>';
print_r($data);
echo '</pre>';
exit;
} 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;
}
} else {
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'public_profile','pages_show_list']; // Optional permissions
$redirect_url = "https://www.example.com/this_file.php";
$loginUrl = $helper->getLoginUrl($redirect_url, $permissions);
echo '<a href="' . $loginUrl . '">Log in with Facebook!</a>';
}
我终于明白了!
问题在于 Facebook AccessToken 是一个具有两个属性的对象:一个字符串代码和一个具有到期时间的日期时间 PHP 对象 - 请参阅以下代码:
Github repository of Facebook's PHP SDK。我第一次获得新令牌时,它的到期时间已设置,一切正常。但是当我将其代码存储在会话中并尝试使用
重新创建它时
$accessToken = new Facebook\Authentication\AccessToken($_SESSION['fb_access_token']);
我没有设置过期时间,对象默认为 UNIX 时间 0(即 1970 年 1 月 1 日)。因为在我调用函数 validateExpiration()
之后,这将 return 访问令牌已过期(它只查看 AccessToken 对象中的过期时间)并将触发异常。
解决方法:不要重新验证存储的令牌。 validateAppId(APP_ID)
继续有效。对于到期时间,要么存储它(例如在会话中)并在重新创建 AccessToken 对象时使用它,要么调用 Graph API。如果此调用 return 出错(可能是因为令牌已过期或用户撤销了权限),请通过 Facebook 登录向用户索取新令牌。
我正在编写一些代码来获取由 Facebook 用户管理的 Facebook 页面,使用 Facebook Graph API。我的代码请求用户的授权并获得一个令牌,使它能够获取此信息,然后将其存储在会话中。问题是,如果我重新加载页面,存储的令牌将被取消设置,我将无法获得由 Facebook 用户管理的 Facebook 页面。
当页面重新加载时,令牌显然已通过 'validateExpiration()' 函数撤销。
我错过了什么?
这是我的代码:
session_start();
// Load the Facebook PHP SDK
require_once __DIR__ . '/facebook-sdk-v5/autoload.php';
define('APP_ID', 'xxxxxxxxxxxxxxxx');
define('APP_SECRET', 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx');
$fb = new Facebook\Facebook([
'app_id' => APP_ID,
'app_secret' => APP_SECRET,
'default_graph_version' => 'v2.7'
]);
if(isset($_SESSION['fb_access_token'])) {
echo '$_SESSION["fb_access_token"] = ' . $_SESSION['fb_access_token'] . '<br>';
// Create a new AccessToken object from its string code. Needed?
$accessToken = new Facebook\Authentication\AccessToken($_SESSION['fb_access_token']);
$expirationDate = $accessToken->getExpiresAt();
echo 'Token expires at: ' . var_dump($expirationDate) . '<br>'; // Returns null!
// verifies the validity and expiration of the token
$oAuth2Client = $fb->getOAuth2Client();
$tokenMetadata = $oAuth2Client->debugToken($accessToken);
try {
echo 'Validating token<br>';
$tokenMetadata->validateAppId(APP_ID);
$tokenMetadata->validateExpiration(); // This apparently throws an exception
} catch(Facebook\Exceptions\FacebookSDKException $e) {
echo 'I will now unset the token<br>';
unset($accessToken);
unset($_SESSION['fb_access_token']);
}
if(!isset($accessToken)){
echo 'Token not set!';
exit;
}
// Check permissions
if (isset($accessToken)) {
$response = $fb->get('/me/permissions', $accessToken);
$permissions = $response->getDecodedBody();
echo 'Permissions: ';
print_r($permissions);
$permissions_list = [];
foreach($permissions['data'] as $perm) {
if($perm['status'] == 'granted') {
$permissions_list[] = $perm['permission'];
}
}
echo 'Permissions list: ';
print_r($permissions_list);
if(!in_array('pages_show_list', $permissions_list)) {
echo 'I will now unset the token<br>';
unset($accessToken);
unset($_SESSION['fb_access_token']);
}
}
} else {
$helper = $fb->getRedirectLoginHelper();
try {
$accessToken = $helper->getAccessToken();
} 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;
}
}
if(isset($accessToken)) {
// Logged in!
// Save the string code of the AccessToken to re-create it later
$_SESSION['fb_access_token'] = (string) $accessToken;
echo '$_SESSION["fb_access_token"] = ' . $_SESSION['fb_access_token'] . '<br>';
try {
$response = $fb->get('/me/accounts', $accessToken);
$data = $response->getDecodedBody();
echo '<pre>';
print_r($data);
echo '</pre>';
exit;
} 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;
}
} else {
$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'public_profile','pages_show_list']; // Optional permissions
$redirect_url = "https://www.example.com/this_file.php";
$loginUrl = $helper->getLoginUrl($redirect_url, $permissions);
echo '<a href="' . $loginUrl . '">Log in with Facebook!</a>';
}
我终于明白了!
问题在于 Facebook AccessToken 是一个具有两个属性的对象:一个字符串代码和一个具有到期时间的日期时间 PHP 对象 - 请参阅以下代码: Github repository of Facebook's PHP SDK。我第一次获得新令牌时,它的到期时间已设置,一切正常。但是当我将其代码存储在会话中并尝试使用
重新创建它时$accessToken = new Facebook\Authentication\AccessToken($_SESSION['fb_access_token']);
我没有设置过期时间,对象默认为 UNIX 时间 0(即 1970 年 1 月 1 日)。因为在我调用函数 validateExpiration()
之后,这将 return 访问令牌已过期(它只查看 AccessToken 对象中的过期时间)并将触发异常。
解决方法:不要重新验证存储的令牌。 validateAppId(APP_ID)
继续有效。对于到期时间,要么存储它(例如在会话中)并在重新创建 AccessToken 对象时使用它,要么调用 Graph API。如果此调用 return 出错(可能是因为令牌已过期或用户撤销了权限),请通过 Facebook 登录向用户索取新令牌。