Problem with Facebook login not matching CSRF state token
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 t开发者_高级运维his
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
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.
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!
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]
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.
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
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
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).
精彩评论