The “state” param from the URL and session do not

2019-01-18 20:32发布

问题:

In facebook documantion

require('include/facebook/autoload.php'); //SDK directory
$fb = new Facebook\Facebook([
'app_id' => '***********',
'app_secret' => '***********************'
]);

$helper = $fb->getRedirectLoginHelper();
$permissions = ['email', 'public_profile']; // optional
$loginUrl = $helper->getLoginUrl('http://www.meusite.com.br/login-callback.php', $permissions);

When direct it to the url $loginUrl, the return is: Facebook SDK returned an error: Cross-site request forgery validation failed. The "state" param from the URL and session do not match

回答1:

I had the same error.

The problem occurred because I did getLoginUrl(...) before getAccessToken()

So rid of getLoginUrl(...) in redirected URL and code should works.



回答2:

I had the same issue and for me that error was occurring because I did not put session_start(); in my login.php page code before calling getLoginUrl(..) and also at the top of login-callback.php page.

Just put session_start(); in your "login" page and "login-callback" page and it will work surely just like it is working for me now.



回答3:

There could be 2 reason for this error:

  1. you didn't call session_start(); before getLoginUrl call
  2. You executed getLoginUrl again in login-callback.php, so state value regenerated and mismatched with the redirected value


回答4:

Possible Fixes : I used the following configuration settings .

Enable WebAuthLogin under the advanced tab . Provide the url in the WebAuthLogin settins as same as that you provide in $loginUrl ;

For example if you use $loginUrl as https://example.com/ use that same in the WebAuthlogin Url $loginUrl = $helper->getLoginUrl('https://example.com/', $permissions);



回答5:

This problem occures also in case that you generate 2 or more login links on the same page (e.g. one for login and other for registration - even both point to the same url, they have just different labels).

Facebook SDK creates/updates $_SESSION[FBRLH_state] for each new generated loginURL. So if there are 2 generated URLs (using $helper->getLoginUrl()) then the $_SESSION[FBRLH_state] is 2-times rewritten and valid only for the last generated URL. Previous login URL becomes invalid. It means that it is not possible to generate 2 valid loginURLs. In case that 2 same URLs are generated then return the first one and avoid call of Facebook SDK for generation of second one.



回答6:

I had the same problem.

The reason for this error is because --->

When "$helper->getLoginUrl" calls, it create a session variable "FB_State", and this is something to FB uses to match the token. Every-time getLoginUrl calls, it create new state. Then after user authorized and redirect back, if you codes cannot detect this event and re-run "$helper->getLoginUrl", then this error will occur.

The solution ->

  1. refine your coding, stop run "$helper->getLoginUrl" again if authorized.

  2. if you already rerun, then set the session variable for the token to NULL if you have, then User can re-authorize again.

  3. when user tries re-authorize, they can remove the authorized APP once or you need to generate new link with "$helper->getReRequestUrl"

Yet, token has be called by "getAccessToken()" before the "$helper->getLoginUrl" or "$helper->getReRequestUrl" runs.

Good Luck!!!!!



回答7:

Finally, looking into FB code, I discovered that the problem "Cross-site request forgery validation failed. Required param “state” missing" and similars are caused by PHP variable $_SESSION['FBRLH_state'] that for some "strange" reason when FB call the login-callback file.

To solve it I store this variable "FBRLH_state" AFTER the call of function $helper->getLoginUrl(...). Is very important to do only after the call of this function due to is inside this function when the variable $_SESSION['FBRLH_state'] is populated.

Below an example of my code in the login.php:

$uri=$helper->getLoginUrl($uri, $permissions);
foreach ($_SESSION as $k=>$v) {                    
    if(strpos($k, "FBRLH_")!==FALSE) {
        if(!setcookie($k, $v)) {
            //what??
        } else {
            $_COOKIE[$k]=$v;
        }
    }
}
var_dump($_COOKIE);

And in the login-callback.php before calling all FB code:

foreach ($_COOKIE as $k=>$v) {
    if(strpos($k, "FBRLH_")!==FALSE) {
        $_SESSION[$k]=$v;
    }
}

Last, but not least, remember also to include code for PHP session so..

if(!session_id()) {
    session_start();
}
...
...
...
...
<?php session_write_close() ?>

I hope this response can help you to save 8-10 hours of work :) Bye, Alex.



回答8:

This issue was a bit confusing for me, because I had to change a line at the facebook src file:

src/Facebook/Helpers/FacebookRedirectLoginHelper.php

at the function: "validateCsrf" like this:

if ($result !== 0) {
        throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.');
    }

And change it into:

if ($result === 0) {
        throw new FacebookSDKException('Cross-site request forgery validation failed. The "state" param from the URL and session do not match.');
    }

I don't know if this makes a violation to the facebook SDK security, so I truly opened to any exlanation or recommendation for this answer.

You may also make the following changes at the facebook app manager:

add your site and callback-url into your facebook app account at:

setting->advanced:Valid OAuth redirect URIs

Don't forget to add another url with slash (/) at the end of each url and check all 4 checkboxes at Client OAuth Settings.



回答9:

I had the same error. Are you using 1 file or 2? I was trying to get by using 1 file but my error was resolved when I split into login.php & fb-callback.php as the documentation recommended. My sessions were being re-written so the state was never saved properly.

Good luck!



回答10:

Happens when the session in missing a needed variable. might be caused by several things. In my case I left the "www" out of the callback URL



回答11:

You could actually be parsing the data from another domain... for example: website.com is different from www .website.com

If you're parsing data from http ://website.com/login.php to http://www.website.com/fb-callback.php this would be a cross-domain problem and the error you are receiving would be because of that....

http ://website.com and http ://www.website.com are the same but the script identifies them as different..... hope that gives insight to the problem.