CSRF状态令牌与提供的FB PHP SDK 3.1.1 Oauth 2.0不匹配

时间:2012-01-23 19:34:41

标签: facebook facebook-graph-api facebook-php-sdk oauth-2.0 csrf

我的服务器日志显示“CSRF状态令牌与提供的不匹配”错误,这似乎几乎每个用户都会发生。但是,用户是创建和/或验证的,我能够检索用户信息。我正在使用Apache的Linux服务器。我也在使用最新的Facebook PHP SDK v.3.1.1谁能告诉我为什么会这样,以及如何解决它?

9 个答案:

答案 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登录

相关问题