我正在尝试使用Facebook PHP SDK构建服务器到服务器的身份验证流程,而不是J {here。到目前为止,我已成功创建了一个LoginUrl,允许用户使用Facebook登录,然后重定向回我的应用程序并检查状态参数以获取CSFR保护。
我的问题是,我似乎无法让API调用工作,应该将我的Auth代码交换为访问令牌。我掠夺了谷歌能够找到的任何其他人遇到的类似问题。 然而最终结果总是相同的:没有访问令牌,没有我可以评估的错误消息。
研究该主题产生了以下建议,我测试过:
$appUrl
。api()
我已经连续两天在这里了,真的可以使用一些帮助。
<?php
require '../inc/php-sdk/src/facebook.php';
// Setting some config vars
$appId = 'MY_APP_ID';
$secret = 'MY_APP_SECRET';
$appUrl = 'https://MY_DOMAIN/appFolder';
$fbconfig = array('appId'=>$appId, 'secret'=>$secret);
$facebook = new Facebook($fbconfig);
// Log User in with Facebook and come back with Auth Code if not yet done
if(!(isset($_SESSION['login']))){
$_SESSION['login']=1;
header('Location: '.$facebook->getLoginUrl());
}
// process Callback from Facebook User Login
if($_SESSION['login']===1) {
/* CSFR Protection: getLoginUrl() generates a state string and stores it
in "$_SESSION['fb_'.$fbconfig['appId'].'_state']". This checks if it matches the state
obtained via $_GET['state']*/
if (isset($_SESSION['fb_'.$fbconfig['appId'].'_state'])&&isset($_GET['state'])){
// Good Case
if ($_SESSION['fb_'.$fbconfig['appId'].'_state']===$_GET['state']) {
$_SESSION['login']=2;
}
else {
unset($_SESSION['login']);
echo 'You may be a victim of CSFR Attacks. Try <a
href="'.$facebook->getLoginUrl().'">logging in</a> again.';
}
}
}
// State check O.K., swap Code for Token now
if($_SESSION['login']===2) {
$path = '/oauth/access_token';
$api_params = array (
'client_id'=>$appId,
'redirect_uri'=>$appUrl,
'client_secret'=>$secret,
'code'=>$_GET['code']
);
$access_token = $facebook->api($path, 'GET', $api_params);
var_dump($access_token);
}
答案 0 :(得分:1)
我发现这样做最简单的方法是扩展Facebook类并公开受保护的getAccessTokenFromCode()方法:
<?php
class MyFacebook extends Facebook {
/** If you simply want to get the token, use this method */
public function getAccessTokenFromCode($code, $redirectUri = null)
{
return parent::getAccessTokenFromCode($code, $redirectUri);
}
/** If you would like to get and set (and extend), use this method instead */
public function setAccessTokenFromCode($code)
{
$token = parent::getAccessTokenFromCode($code);
if (empty($token)) {
return false;
}
$this->setAccessToken($token);
if (!$this->setExtendedAccessToken()) {
return false;
}
return $this->getAccessToken();
}
}
我还提供了一个用于设置访问令牌的方便方法的变体,因为我实际上并不需要在我自己的代码中使用公共“get”方法。