重定向后Firefox无法存储PHP会话 [英] PHP Session not being stored by Firefox after redirect

查看:61
本文介绍了重定向后Firefox无法存储PHP会话的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Facebook的服务器端用户身份验证来尝试将人们登录到我们的网站.为了防止CSRF,Facebook建议创建一个随机会话状态变量,将其传递给FB,然后FB将其传递回以比较这些值,以确保没有安全问题.这似乎在除Firefox之外的所有浏览器中都可以正常工作. Firefox正在发送状态变量,但是在返回站点时不会存储状态变量. session_start()出现在文档的顶部,但出于安全原因我去除了一些变量和其他代码,因此未在下面引用.

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转到显示错误消息的其他地方.我稍后在文档中返回了$ _SESSION ['state']的值,该值将为NULL.

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.

此外,我在会话中添加了一个名为test的测试变量,Firefox很好地存储了该变量.我想念什么?

Additionally, I added a test variable to the session, called test, and it was stored fine by Firefox. What am I missing?

谢谢.

编辑:似乎Firefox愿意将会话变量存储在if语句之外.如果在if语句之前设置$ _SESSION ['myny_state'],则当FB返回$ code时,它将存储该值.这里的问题是状态肯定不匹配,因为现在它位于if语句之外,因此每次页面调用都将重置该状态.

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.

推荐答案

在密切关注Firefox内部发生的情况之后,我注意到Firefox会从域名中剥离"www",即使该地址最初包含在其中"www."然后,该会话被保存到 http://domain.com/whatever ,同时Facebook应用将用户重定向回到 http://www.domain.com/whatever .

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.

有两种方法可以解决此问题.我选择使用.htaccess重写条件来解决此问题:

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]

这也可以通过如下设置session.cookie_domain来实现:

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.

请注意,强制您的网站在使用www或不使用www的情况下(不同时使用)使用SEO是一种很好的做法.

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.

这篇关于重定向后Firefox无法存储PHP会话的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆