Fad*_*adi 57 php wordpress facebook facebook-graph-api
我正在尝试使用像这样的php sdk获取Facebook用户ID
$fb = new Facebook\Facebook([
'app_id' => '11111111111',
'app_secret' => '1111222211111112222',
'default_graph_version' => 'v2.4',
]);
$helper = $fb->getRedirectLoginHelper();
$permissions = ['public_profile','email']; // Optional permissions
$loginUrl = $helper->getLoginUrl('http://MyWebSite', $permissions);
echo '<a href="' . $loginUrl . '">Log in with Facebook!</a>';
try {
$accessToken = $helper->getAccessToken();
var_dump($accessToken);
} catch (Facebook\Exceptions\FacebookResponseException $e) {
// When Graph returns an error
echo 'Graph returned an error: ' . $e->getMessage();
exit;
} catch (Facebook\Exceptions\FacebookSDKException $e) {
// When validation fails or other local issues
echo 'Facebook SDK returned an error: ' . $e->getMessage();
exit;
}
if (!isset($accessToken)) {
if ($helper->getError()) {
header('HTTP/1.0 401 Unauthorized');
echo "Error: " . $helper->getError() . "\n";
echo "Error Code: " . $helper->getErrorCode() . "\n";
echo "Error Reason: " . $helper->getErrorReason() . "\n";
echo "Error Description: " . $helper->getErrorDescription() . "\n";
} else {
header('HTTP/1.0 400 Bad Request');
echo 'Bad request';
}
exit;
}
// Logged in
echo '<h3>Access Token</h3>';
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);
echo '<h3>Metadata</h3>';
var_dump($tokenMetadata);
// Validation (these will throw FacebookSDKException's when they fail)
$tokenMetadata->validateAppId($config['11111111111']);
// 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) {
echo "<p>Error getting long-lived access token: " . $helper->getMessage() . "</p>\n\n";
exit;
}
echo '<h3>Long-lived</h3>';
var_dump($accessToken->getValue());
}
$_SESSION['fb_access_token'] = (string)$accessToken;
Run Code Online (Sandbox Code Playgroud)
但它给了我这个错误:
Facebook SDK returned an error:
Cross-site request forgery validation failed.
The "state" param from the URL and session do not match.
Run Code Online (Sandbox Code Playgroud)
请任何帮助我是新的PHP和Facebook sdk感谢任何提前帮助.
eno*_*rev 99
我发现只要我在生成登录URL之前启用了PHP会话,并且在Facebook最终重定向到脚本的顶部,它就可以自行运行而无需设置cookie(根据ale500的答案).这是使用sdk的5.1版本.
在两个脚本的顶部,我添加了......
if(!session_id()) {
session_start();
}
Run Code Online (Sandbox Code Playgroud)
......它"刚刚奏效".
这是一个适合我的准系统完整示例:
auth.php
if (!session_id()) {
session_start();
}
$oFB = new Facebook\Facebook([
'app_id' => FACEBOOK_APP_ID,
'app_secret' => FACEBOOK_APP_SECRET
]);
$oHelper = self::$oFB->getRedirectLoginHelper();
$sURL = $oHelper->getLoginUrl(FACEBOOK_AUTH_CALLBACK, FACEBOOK_PERMISSIONS);
// Redirect or show link to user.
Run Code Online (Sandbox Code Playgroud)
auth_callback.php
if (!session_id()) {
session_start();
}
$oFB = new Facebook\Facebook([
'app_id' => FACEBOOK_APP_ID,
'app_secret' => FACEBOOK_APP_SECRET
]);
$oHelper = self::$oFB->getRedirectLoginHelper();
$oAccessToken = $oHelper->getAccessToken();
if ($oAccessToken !== null) {
$oResponse = self::$oFB->get('/me?fields=id,name,email', $oAccessToken);
print_r($oResponse->getGraphUser());
}
Run Code Online (Sandbox Code Playgroud)
作为补充说明,这在回购文件中有解释.请查看此页面上的警告.
警告:FacebookRedirectLoginHelper使用会话来存储CSRF值.在调用getLoginUrl()方法之前,您需要确保已启用会话.这通常在大多数Web框架中自动完成,但如果您不使用Web框架,则可以添加session_start(); 登录login.php和login-callback.php脚本的顶部.您可以覆盖默认会话处理 - 请参阅下面的扩展点.
我正在添加此注释,因为如果您正在运行自己的会话管理或者并行运行多个Web服务器,请务必记住这一点.在这些情况下,依赖php的默认会话方法并不总是有效.
小智 64
在$ helper = $ fb-> getRedirectLoginHelper()之后插入此代码;
$_SESSION['FBRLH_state']=$_GET['state'];
Run Code Online (Sandbox Code Playgroud)
它将工作或更多细节访问Facebook登录应用程序
G.A*_*mar 49
已经提到了很多很棒的答案,这里有一个对我有帮助的答案,
我发现问题是跨站点请求伪造验证失败.FB代码中缺少必需的参数"状态",这是解决方案
这一行之后
$helper = $fb->getRedirectLoginHelper();
Run Code Online (Sandbox Code Playgroud)
添加以下代码,
if (isset($_GET['state'])) {
$helper->getPersistentDataHandler()->set('state', $_GET['state']);
}
Run Code Online (Sandbox Code Playgroud)
okd*_*wit 22
我在Symfony2中使用Facebook SDK时出现此错误,编写Twig扩展以在模板中显示来自API的数据.
我的解决方案是添加'persistent_data_handler'=>'session'到Facebook对象配置,这会导致状态数据存储在会话密钥而不是内存中:
$fb = new Facebook\Facebook([
'app_id' => 'APP_ID',
'app_secret' => 'APP_SECRET',
'default_graph_version' => 'v2.4',
'persistent_data_handler'=>'session'
]);
Run Code Online (Sandbox Code Playgroud)
默认情况下,它使用的内置内存处理程序对我来说无法正常工作.也许是因为某些函数是在Twig扩展中调用的,因为内存处理程序在普通控制器/服务中专门使用SDK时可以正常工作.
显然,当你打电话时getLoginUrl(),状态就会被设定,并且在你打电话的时候被检索getAccessToken().如果保存的状态返回null(因为您的数据处理程序不像应该的那样持久),则CSRF验证检查失败.
如果您需要以特定方式处理会话,或者您希望将状态存储在其他位置,您也可以'persistent_data_handler' => new MyPersistentDataHandler()使用FacebookSessionPersistentDataHandler作为示例编写自己的处理程序.
Geo*_*rge 16
当Facebook库无法将其从Facebook收到的状态参数与默认情况下在会话中设置的状态参数匹配时,就会发生这种情况.如果您使用的是Laravel,Yii2或Kohana等框架来实现自己的会话存储,那么标准的Facebook会话实现可能无法正常工作.
要修复它,您需要PersistentDataInterface使用框架的会话库创建自己的实现,并将其传递给Facebook\Facebook构造函数.
以下是来自Facebook的Laravel持久性处理程序的示例:
use Facebook\PersistentData\PersistentDataInterface;
class MyLaravelPersistentDataHandler implements PersistentDataInterface
{
/**
* @var string Prefix to use for session variables.
*/
protected $sessionPrefix = 'FBRLH_';
/**
* @inheritdoc
*/
public function get($key)
{
return \Session::get($this->sessionPrefix . $key);
}
/**
* @inheritdoc
*/
public function set($key, $value)
{
\Session::put($this->sessionPrefix . $key, $value);
}
}
Run Code Online (Sandbox Code Playgroud)
示例构造函数参数:
$fb = new Facebook\Facebook([
// . . .
'persistent_data_handler' => new MyLaravelPersistentDataHandler(),
// . . .
]);
Run Code Online (Sandbox Code Playgroud)
更多信息:https: //developers.facebook.com/docs/php/PersistentDataInterface/5.0.0
小智 8
最后,看看FB代码,我发现了这个问题
跨站点请求伪造验证失败.必需的参数"状态"缺失
和similars是由PHP变量引起的,$_SESSION['FBRLH_state']当FB调用login-callback文件时出于某种"奇怪"的原因.
为了解决这个问题,我"FBRLH_state"在调用函数后存储了这个变量$helper->getLoginUrl(...).只有在调用此函数后才能执行此操作,因为当$_SESSION['FBRLH_state']填充变量时,此功能位于此函数内部.
下面是我在login.php中的代码示例:
$uri=$helper->getLoginUrl($uri, $permissions);
foreach ($_SESSION as $k=>$v) {
if(strpos($k, "FBRLH_")!==FALSE) {
if(!setcookie($k, $v)) {
//what??
} else {
$_COOKIE[$k]=$v;
}
}
}
var_dump($_COOKIE);
Run Code Online (Sandbox Code Playgroud)
在调用所有FB代码之前的login-callback.php中:
foreach ($_COOKIE as $k=>$v) {
if(strpos($k, "FBRLH_")!==FALSE) {
$_SESSION[$k]=$v;
}
}
Run Code Online (Sandbox Code Playgroud)
最后,但并非最不重要的是,还记得包含PHP会话的代码,所以..
if(!session_id()) {
session_start();
}
...
...
...
...
<?php session_write_close() ?>
Run Code Online (Sandbox Code Playgroud)
我希望这个回复可以帮助你节省8-10个小时的工作:)再见,亚历克斯.