16

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

Pedro Henrique
  • 181
  • 1
  • 1
  • 5
  • 2
    That most likely indicates a problem with the PHP session, like the session id not getting passed properly. – CBroe Jul 10 '15 at 18:46
  • 2
    It is a problem with the PHP session. I solved the same problem by moving to the beginning of the page. (It had moved down some because of some editor I was using inserting header before it...). I thought about enabling session.auto_start = 1 in php.ini, but new at this and figured maybe that would cause head-scratching when other scripts try to start a session that is already started. – hellork Oct 04 '15 at 20:24
  • @hellork thanks , that's the problem... fixed it by putting session_start(); at the first line – Partha Roy Feb 29 '16 at 05:22

11 Answers11

28

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.

tasmaniski
  • 4,767
  • 3
  • 33
  • 65
17

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.

gauravparmar
  • 884
  • 1
  • 9
  • 23
6

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
Shaon
  • 61
  • 2
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);

TheVigilant
  • 720
  • 8
  • 16
4

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.

Mojo
  • 187
  • 3
  • 14
3

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!!!!!

Micah
  • 4,254
  • 8
  • 30
  • 38
2

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.

ale500
  • 270
  • 2
  • 10
1

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.

Tariq
  • 2,853
  • 3
  • 22
  • 29
  • Hi Ahmed, I have a similar problem but with the following error: - Facebook SDK returned an error: Cross-site request forgery validation failed. Required param "state" missing. I tried your suggestions above but no luck. If I var-dump $_GET i can see the "code" and "state" codes but if I var_dump $_SESSION neither is returned? – Tatters Jul 23 '15 at 12:36
  • 2
    That is not a fix for the issue, but it simply _negates_ what this security feature is intended to do. You should investigate the problem to find the real cause instead (as I commented already, this is in most cases a problem with the PHP session.) – CBroe Jul 24 '15 at 19:06
1

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!

Erica
  • 11
  • 1
0

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

Roy Toledo
  • 643
  • 4
  • 20
-2

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.

  • This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient [reputation](http://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](http://stackoverflow.com/help/privileges/comment). – danielschemmel Sep 18 '15 at 10:46
  • I re-wrote it as to provide the answer so its more easily understood.... The answer WAS in the post, but edited so it makes more sense.... problem is difference between http ://website.com and http ://www.website.com which the session recognises AS a cross-domain error. – SiriusAnkh Sep 19 '15 at 11:53