问题
I'm using Facebook's server-side user authentication to attempt to log people in to our site. To prevent CSRF, Facebook recommends creating a random session state variable, pass it to FB, and FB then passes it back to compare the values to ensure no security issues. This seems to work fine in all browsers except Firefox. Firefox is sending the state variable, but it is not storing it upon return to the site. session_start() appears at the top of the document which is not quoted below as I stripped out some variables and other code for security reason.
if(empty($code)) {
$rand = md5(uniqid(rand(), TRUE)); // CSRF protection
$_SESSION['mbny_state'] = $rand;
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_SESSION['mbny_state'] . "&scope=publish_stream,user_birthday,user_hometown,email";
header('Location: ' . $dialog_url);
}
$state = $_REQUEST['state'];
$secret_state = $_SESSION['state'];
// Check session state to prevent hacking
if($secret_state == $state) {
$token_url = "https://graph.facebook.com/oauth/access_token?"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
$params = null;
parse_str($response, $params);
// store the access token for future requests
$_SESSION['access_token'] = $params['access_token'];
// define graph url allowing us to communicate with FB with user's account
$graph_url = "https://graph.facebook.com/me?access_token="
. $params['access_token'];
$user = json_decode(file_get_contents($graph_url));
}
else {
$error_message = 'An error has occurred. Your session ID does not match. Please exit and try again.<br /><br />' . $secret_state . ' :: ' . $state . ' :: ' . $_SESSION['test'];
}
Firefox makes it to the else displaying the error message. I have returned the value of $_SESSION['state'] later in the document, and it is coming up NULL.
Additionally, I added a test variable to the session, called test, and it was stored fine by Firefox. What am I missing?
Thanks in advance.
Edit: It appears as if Firefox is willing to store session variables outside of the if statement. If I set $_SESSION['myny_state'] prior to the if statement, it stores that value when FB returns back with the $code. The problem here is that the state definitely doesn't match because it is being reset with every page call now that it is outside the if statement.
I'm losing hair as we speak.
回答1:
After paying some really close attention to what was happening within Firefox, I noticed that Firefox was stripping the 'www' from the domain name even though the address originally included the 'www.' The session was then being saved to http://domain.com/whatever while the Facebook app was redirecting the user back to http://www.domain.com/whatever.
There are two ways to resolve this. I chose to fix this utilizing an .htaccess rewrite condition:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]
This could also be achieved by setting the session.cookie_domain as follows:
ini_set('session.cookie_domain', '.domain.com');
Hope someone finds this useful. Perhaps it'll save you five hours of debugging something that is actually bug free.
As a side note, it's considered good SEO practice to force your website to utilize either with the www or without the www - not both.
回答2:
$_SESSION
vars are stored server-side, not client-side.
- Are you calling
session_start()
somewhere? Because it's not in the code you quoted. - Are cookies disabled in your browser? IIRC PHP usually sets a cookie with
PHPSESSID
to connect the client browser with the server's session data.
re-edit
Facebook might be stripping out your state variable since it's not urlencoded. Try replacing:
urlencode($my_url) . "&state=" . $_SESSION['state']
with:
urlencode($my_url . "&state=" . $_SESSION['state'])
回答3:
If that is your full code, you have to add session_start();
at the top or just before you are starting to work with Session varibles.
Also, you need to add session_start();
on all pages that you want to add/retrieve data.
回答4:
Sometimes to restart your Firefox browser can solve the problem. I don't know why, but it works.
来源:https://stackoverflow.com/questions/13458776/php-session-not-being-stored-by-firefox-after-redirect