我正在使用SammyK / Facebook软件包,并面临着通过CSRF登录facebook的问题。之前它运行良好,但后来我不得不在我的kernel.php中禁用CSRF保护,以便顺利运行API。现在我更新了它并在中间件
中添加了以下行 public function handle($request, Closure $next) {
$skip = array(
'api/v1/signup',
'api/v1/login',
'api/v1/addContacts',
'api/v1/email'
);
foreach ($skip as $key => $route) {
//skip csrf check on route
if($request->is($route)){
return parent::addCookieToResponse($request, $next($request));
}
}
return parent::handle($request, $next);
}
因此,这允许web和api按预期工作,但由于我已禁用csrf,因此我得到跨站点请求伪造验证失败。必需的参数"州"我登录FB时错过了错误。我尝试调试并在FacebookRedirectLoginHelper中找到函数validateCsrf()
没有得到保存状态$savedState = $this->persistentDataHandler->get('state');
我不知道如何解决这个问题,因为理想情况下它现在可以正常工作。我尝试打印$ state和$ savedState,并将$ savedState视为null。
class FacebookController extends Controller {
public function fbConnect(LaravelFacebookSdk $fb)
{
// Obtain an access token.
try {
$token = $fb
->getRedirectLoginHelper()
->getAccessToken();
} catch (Facebook\Exceptions\FacebookSDKException $e) {
dd($e->getMessage());
}
// Access token will be null if the user denied the request
// or if someone just hit this URL outside of the OAuth flow.
if (! $token) {
// Get the redirect helper
$helper = $fb->getRedirectLoginHelper();
if (! $helper->getError()) {
abort(403, 'Unauthorized action.');
}
// User denied the request
dd(
$helper->getError(),
$helper->getErrorCode(),
$helper->getErrorReason(),
$helper->getErrorDescription()
);
}
答案 0 :(得分:6)
最后,看一下FB代码,我发现问题"跨站点请求伪造验证失败。必需的参数“状态”缺失"和类似物是由PHP变量$ _SESSION [' FBRLH_state']引起的,对某些人而言,#34;奇怪的" 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);
在调用所有FB代码之前的login-callback.php中:
foreach ($_COOKIE as $k=>$v) {
if(strpos($k, "FBRLH_")!==FALSE) {
$_SESSION[$k]=$v;
}
}
最后,但并非最不重要的是,还要记住包含PHP会话的代码,以便......
if(!session_id()) {
session_start();
}
...
...
...
...
<?php session_write_close() ?>
我希望这个回复可以帮助你节省8-10个小时的工作:) 再见,亚历克斯。
答案 1 :(得分:1)
对于使用Code Igniter的用户,您必须自动加载会话库。
更改您的application / config / autoload.php,库必须包含'session':
$autoload['libraries'] = array('session');
答案 2 :(得分:0)
这是我的头疼,然后我找到了一种简单的方法来解决它。
找到config / session.php并更改
'expire_on_close' => false,
到
'expire_on_close' => true,