我的服务器日志显示“CSRF状态令牌与提供的不匹配”错误,这似乎几乎每个用户都会发生。但是,用户是创建和/或验证的,我能够检索用户信息。我正在使用Apache的Linux服务器。我也在使用最新的Facebook PHP SDK v.3.1.1谁能告诉我为什么会这样,以及如何解决它?
答案 0 :(得分:35)
上周我遇到了类似的问题,并将其跟踪到被state
多次调用覆盖的getLoginUrl()
字段。每次调用getLoginUrl()
时,SDK中都会生成一个新的state
令牌并存储在$_SESSION
中(它只是一个随机值),因此如果您调用它两次并且用户使用登录的第一个链接,第二个调用将重置SDK的内部state
令牌,您将在日志中收到此错误。
SDK会在Facebook授权用户并将其重定向回您的网站后在URL中查找相同的state
令牌,如果它不匹配,则会记录此错误(这是一个链接到source)。
答案 1 :(得分:8)
Facebook SDK代码在同一个处理程序中两次检查令牌时有一个错误。
我编辑了facebook.php
的getCode函数,如下所示:
protected function getCode() {
if (!isset($_REQUEST['code']) || !isset($_REQUEST['state']) || $this->state === null) {
return false;
}
if ($this->state === $_REQUEST['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $_REQUEST['code'];
}
self::errorLog('CSRF state token does not match one provided.');
return false;
}
更清楚,如果被调用两次则不会声明无效令牌。
要清楚,如果例如:
,可以在同一个url处理程序上调用该函数两次 $facebook->getUser();
然后在同一个处理程序$facebook->getLogoutUrl()
中,getCode()
被调用两次,从而导致错误消息无效
答案 2 :(得分:3)
好吧,我曾经遇到过这个确切的问题,我遇到了state
&问题。 URL中的code
个参数 - 我的.htaccess
文件未转发它们。
我猜你有同样的问题。
CSRF state token does not match one provided
希望这有帮助
答案 3 :(得分:2)
要向chesles的答案添加一点,如果您正在使用session_start() - session_write_close()函数,就会出现此问题。
如果您在请求loginUrl时没有启动会话,则会收到此错误。
旁注:为什么还要停止会话?
使用会话的脚本互相停止,因为它们正在等待会话数组可供使用。
想象一下,你有一个受欢迎的应用程序,有成千上万的用户,并有一个动作(一个PHP脚本),你发布图片。 像这样:
- 在脚本顶部开始会话
- 连接到Facebook
- 创建图片
- 使用api调用共享图像
- 脚本结束,会话自动关闭
这样做,脚本会长时间无故地使用该会话。 小心使用这样的脚本,改为使用类似的东西:
- 在创建facebook对象之前开始会话
- 连接到Facebook
- 使用session_write_close()关闭会话,会话数组可用,其他脚本可以加载
- 创建图片
- 使用api调用共享图像/ *它认为这不需要会话。 * /
- 脚本结束,会话已经手动关闭。
干杯。
答案 4 :(得分:2)
另外一个注意事项 - 尽管Facebook PHP API文档中没有说明,但您必须为PHP会话配置apache才能使登录过程正常工作。结果证明,当我们得到“CSRF状态令牌与提供的令牌不匹配”时,我们遇到的问题。
确保您使用的服务器池设置为使用memcache来获取会话信息,否则apache将在本地写入会话信息,如果下一个请求未转到同一服务器,您将获得“CSRF状态令牌与提供的令牌不匹配”。
这是在开发环境(具有一个服务器)中起到魅力但在生产中失败的那些事情之一。
我们还必须重新配置我们的CDN设置,以确保我们通过PHP Session cookie。
答案 5 :(得分:2)
我有同样的问题。这很简单。不要打电话
$fbLoginUrl = $facebook->getLoginUrl(...);
之前
$fbUser = $facebook->getUser();
否则你会得到“CSRF状态令牌与提供的一个不匹配”错误。
答案 6 :(得分:1)
我在本地计算机上遇到了同样的问题,问题是我的主机文件阻止了与Verisign的通信,因此Facebook尝试与之通信(http://crl.verisign.com/pca3.crl从未工作过(州:404)。
从我的主机文件中注释掉各种Verisign IP地址就行了!
答案 7 :(得分:0)
使用本地会话检查CSRF状态和代码,我打赌你需要检查你的php.ini中的session.save_handler,以及它是否正常工作。
答案 8 :(得分:0)
如果在页面上使用.htaccess mod rewrite重定向,请使用行尾的[QSA](查询字符串追加)来保留GET变量,否则就会丢失$ code变量,这是必需的facebook登录