我的服务器日志显示"CSRF状态令牌与提供的不匹配"错误,几乎每个用户都会出现这个问题。但是,用户已经被创建和/或身份验证,并且我能够检索到用户信息。我正在使用带有Apache的Linux服务器。我也在使用最新的Facebook PHP SDK v.3.1.1。有人可以告诉我为什么会发生这种情况以及如何解决吗?
我的服务器日志显示"CSRF状态令牌与提供的不匹配"错误,几乎每个用户都会出现这个问题。但是,用户已经被创建和/或身份验证,并且我能够检索到用户信息。我正在使用带有Apache的Linux服务器。我也在使用最新的Facebook PHP SDK v.3.1.1。有人可以告诉我为什么会发生这种情况以及如何解决吗?
state
字段被多次调用getLoginUrl()
覆盖。每次调用getLoginUrl()
都会在SDK中生成一个新的state
令牌并存储在$_SESSION
中(它只是一个随机值),所以如果你调用两次并且用户使用第一个链接登录,第二个调用会重置SDK内部的state
令牌,然后你将在日志中收到此错误。state
令牌,如果不匹配,则记录此错误(这里是源代码链接)。getLoginUrl()
的不必要调用。 - SSH This在同一处理程序中两次检查令牌时,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()
两次,从而导致无效错误消息。
需要注意的一点是,虽然Facebook PHP API文档中没有明确说明,但你必须为PHP会话配置apache才能使登录过程正常工作。这就是当我们遇到“CSRF状态令牌与提供的令牌不匹配”错误时遇到的问题。
如果您正在使用服务器池,请确保已设置为使用memcache进行会话信息,否则apache将在本地编写会话信息,如果下一个请求不发送到同一台服务器,则会收到“CSRF状态令牌与提供的令牌不匹配”的错误消息。
这是其中一件在开发环境(使用一台服务器)中完美运行但在生产环境中失败的事情。
我们还必须重新配置CDN设置,以确保通过PHP会话cookie。
$fbLoginUrl = $facebook->getLoginUrl(...);
之前
$fbUser = $facebook->getUser();
本地会话检查 CSRF 状态和代码,我敢打赌您需要检查您的 php.ini 中的 session.save_handler 是否正常工作。