5

I did some searches and I didn't find anything that was related to my problem.

I'm currently trying to implement a Facebook login to my website and I'm having problems with the login authentication due to htaccess mod rewrite URLs?

The code works perfectly and I get logged in if I use it without the mod rewrite rules like:

domain.com/view_webhosting.php?webhosting=name

But as soon as I go over to the mod rewrite URL

domain.com/webhosting-name/

Then it just doesnt work and throws a error "CSRF state token does not match one provided."

in the htaccess file it looks like this

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

Anyone have a solution to a problem like this? I am using Facebook SDK v3.1.1

phwd
  • 19,975
  • 5
  • 50
  • 78
John
  • 387
  • 2
  • 5
  • 17

7 Answers7

7

The PHP SDK expects the 'state' field to be in $_REQUEST (I believe as a GET param) after the redirect before you can exchange the 'code' for an access token. From 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;
}

Your RewriteRule may be stomping on that param.

bismark
  • 560
  • 1
  • 3
  • 10
7

Thanks bismark.

You were correct; it couldn't get the GET parameters, and the solution was this:

From

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

to

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

Query string append [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.

Thanks guys, put me on the right track!

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
John
  • 387
  • 2
  • 5
  • 17
  • 1
    If bismark is correct, it is nice to accept the answer or at very least vote up. I have voted up your question to give you a little rep to play with. – Fionnuala Sep 09 '11 at 09:11
  • Hello Remou, ur absolutely right, im kinda new to this webpage so i didnt know i could vote or accept answers :) – John Sep 16 '11 at 08:20
2

I assume you mean the PHP SDK?

Sounds like you're not passing the 'state' request variable to your PHP script. Have you read https://developers.facebook.com/docs/authentication/ (specifically the bits and protecting yourself from CSRF?).

Also, I assume this is a typo in your question, but shouldn't your rewrite rule be:

RewriteRule ^webhosting-([a-z_0-9-]+)/$ /view_webhosting.php?**webhosting**=$1 [L]
mrtom
  • 2,148
  • 1
  • 14
  • 21
  • Hello mrtom Yeah sorry thats just a typ, i figured it would be easier to read when i translated it to english :) The example im using is https://github.com/facebook/php-sdk/blob/master/examples/example.php and there's nothing about CSRF protection? this facebook API is weird with different codes all over the place. but it does work properly when not using the mod rewrite url... – John Sep 07 '11 at 22:00
1

Try changing your RewriteRule to

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

QSA = Query String Append. This ensures you don't lose your GET params.

Gigablah
  • 1,361
  • 15
  • 9
0

If someone still gets this error after the .htaccess file I'll suggest to change the redirect_uri parameter at the PHP file as well as Site URL at Facebook app settings.

I solved this error changing from

http:domain.com/folder

to

http:domain.com/folder/index.php

Stephan
  • 41,764
  • 65
  • 238
  • 329
miguelglz
  • 417
  • 1
  • 4
  • 16
0

The Facebook SDK code has a bug when checking against tokens twice in the same handler.

I edited the getCode function of facebook.php like this:

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;
}

to be more clear and does not state an invalid token if called twice.

To be clear the function can be called twice on the same URL handler if for example:

$facebook->getUser(); and then in the same handler $facebook->getLogoutUrl() then the getCode() is called twice thus resulting into and invalid error message

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Jimmy Kane
  • 16,223
  • 11
  • 86
  • 117
-1

I fixed this by (forgetting) to match up scope/permissions from an application to the permissions on the developers.facebook.com/app page... (i.e. goto app settings, permissions).

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131