Facebook登录与CSRF状态令牌不匹配的问题

Facebook登录与CSRF状态令牌不匹配的问题,facebook,.htaccess,facebook-php-sdk,Facebook,.htaccess,Facebook Php Sdk,我做了一些搜索,没有找到任何与我的问题有关的东西 我目前正在尝试实现Facebook登录到我的网站,但由于htaccess mod rewrite URL,我在登录身份验证方面遇到了问题 该代码工作正常,如果我使用它而不使用mod rewrite规则,则会登录,如: domain.com/view_webhosting.php?webhosting=name 但只要我转到mod rewrite URL domain.com/webhosting-name/ 然后它就不工作了,并抛出一个错误“

我做了一些搜索,没有找到任何与我的问题有关的东西

我目前正在尝试实现Facebook登录到我的网站,但由于htaccess mod rewrite URL,我在登录身份验证方面遇到了问题

该代码工作正常,如果我使用它而不使用mod rewrite规则,则会登录,如:

domain.com/view_webhosting.php?webhosting=name
但只要我转到mod rewrite URL

domain.com/webhosting-name/
然后它就不工作了,并抛出一个错误“CSRF状态令牌与提供的不匹配”

在htaccess文件中,它如下所示

RewriteRule ^webhosting-([a-z_0-9-]+)/$ /view_webhosting.php?webhosting=$1 [L]

有人能解决这样的问题吗?我使用的是Facebook SDK v3.1.1

我想你是指PHP SDK吧

听起来您没有将“state”请求变量传递给PHP脚本。您是否阅读过(特别是bits和保护自己免受CSRF的影响?)

另外,我认为这是你问题中的一个输入错误,但你的重写规则不应该是:

RewriteRule ^webhosting-([a-z_0-9-]+)/$ /view_webhosting.php?**webhosting**=$1 [L]

PHPSDK希望在重定向之后,$_请求(我相信是一个GET参数)中包含“state”字段,然后才能将“code”交换为访问令牌。从base_facebook.php:

protected function getCode() {
  if (isset($_REQUEST['code'])) {
    if ($this->state !== null &&
      isset($_REQUEST['state']) &&
      $this->state === $_REQUEST['state']) {

      // CSRF state has done its job, so clear it
      $this->state = null;
      $this->clearPersistentData('state');
      return $_REQUEST['code'];
    } else {
      self::errorLog('CSRF state token does not match one provided.');
      return false;
    }
  }

  return false;
}

您的重写规则可能正在践踏该参数。

尝试将您的重写规则更改为

RewriteRule ^webhosting-([a-z_0-9-]+)/$ /view_webhosting.php?webhosting=$1 [L,QSA]
QSA=查询字符串追加。这确保您不会丢失GET参数。

谢谢bismark

你是对的;它无法获取get参数,解决方案如下:

查询字符串追加[QSA]

•'qsappend|QSA' (query string append)
This flag forces the rewrite engine to append a query string part of the substitution string
to  the existing string, instead of replacing it. Use this when you want to add more data
to the query string via a rewrite rule.

谢谢你们,让我走上正轨

如果有人在.htaccess文件之后仍然出现此错误,我建议更改PHP文件中的redirect_uri参数以及Facebook应用程序设置中的站点URL

我解决了这个错误,从

http:domain.com/folder


http:domain.com/folder/index.php
我通过(忘记)将应用程序的范围/权限与
developers.facebook.com/app
页面上的权限相匹配来修复此问题。。。(即转到应用程序设置、权限)。

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()
两次,从而导致无效的错误消息

Hello mrtom Yeah抱歉,这只是一个类型,我想当我把它翻译成英文的时候会更容易阅读:)我使用的例子是,没有关于CSRF保护的内容?这个facebook API很奇怪,到处都有不同的代码。但是,当不使用mod rewrite url时,它确实可以正常工作……如果bismark是正确的,那么接受答案或者至少投赞成票就好了。我投票了你的问题,给你一个小小的代表。你好,Remou,你完全正确,我有点新到这个网页,所以我不知道我可以投票或接受答案:)你可能想更具体一点。
•'qsappend|QSA' (query string append)
This flag forces the rewrite engine to append a query string part of the substitution string
to  the existing string, instead of replacing it. Use this when you want to add more data
to the query string via a rewrite rule.
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;
}