【问题标题】:PHP Session not being stored by Firefox after redirect重定向后 Firefox 未存储 PHP 会话
【发布时间】:2019-10-06 23:41:19
【问题描述】:

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

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。

此外,我在会话中添加了一个名为 test 的测试变量,它被 Firefox 很好地存储了。我错过了什么?

提前致谢。

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

我们说话的时候我正在掉头发。

【问题讨论】:

  • 您是否使用 session_start() 开始会话; ?
  • 你添加了 session_start();一开始?
  • 是的,session_start() 是在文档顶部声明的。刚刚编辑了原始帖子以反映这一点。
  • 这只是服务器端编程。我也有同样的问题,我们将继续,直到有真正的大学课程,而不仅仅是黑客和希望。

标签: php session facebook-graph-api


【解决方案1】:

在仔细观察了 Firefox 中发生的事情后,我注意到 Firefox 正在从域名中删除“www”,尽管该地址最初包含“www”。然后会话被保存到http://domain.com/whatever,而 Facebook 应用程序将用户重定向回http://www.domain.com/whatever

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

RewriteEngine on
RewriteCond %{HTTP_HOST} ^domain.com [NC]
RewriteRule ^(.*)$ http://www.domain.com/$1 [L,R=301]

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

ini_set('session.cookie_domain', '.domain.com');

希望有人觉得这很有用。也许它会为您节省 5 个小时的调试时间,而这些东西实际上是没有错误的。

作为旁注,强制您的网站使用 www 或不使用 www 被认为是良好的 SEO 做法 - 不能同时使用。

【讨论】:

  • 感谢您的解决方案。我遇到了类似的问题,如果您在标题栏 (domain.com) 中键入域名,firefox 会自动将 www 更改为 (www.domain.com)。这个“有用的功能”导致 cookie 域不符合我的预期并破坏了我的网站。所以,感谢您为我指明正确的方向。如果$_SERVER["SERVER_NAME"] 不符合我的预期,我的解决方案是在 PHP 中强制重定向。
  • @Joe 很高兴我能帮上忙!我也会记住您的问题和解决方案。感谢您的分享,感谢您的感谢。
【解决方案2】:

$_SESSION 变量存储在服务器端,而不是客户端。

  1. 你在哪里打电话给session_start()?因为它不在您引用的代码中。
  2. 您的浏览器是否禁用了 cookie? IIRC PHP 通常使用PHPSESSID 设置一个cookie,以将客户端浏览器与服务器的会话数据连接起来。

重新编辑

Facebook 可能会删除您的状态变量,因为它不是 urlencoded。尝试替换:

urlencode($my_url) . "&state=" . $_SESSION['state']

与:

urlencode($my_url . "&state=" . $_SESSION['state'])

【讨论】:

  • session_start() 在文档开头被调用。 Facebook 正在接收和发回状态,没有任何问题。 $_REQUEST['state'] 作为错误消息的一部分被正确返回。它根据 dialog_url 匹配 FB 作为状态接收的内容。
【解决方案3】:

如果这是您的完整代码,您必须在顶部或开始使用 Session 变量之前添加 session_start();

此外,您需要在要添加/检索数据的所有页面上添加session_start();

【讨论】:

    【解决方案4】:

    有时重启你的火狐浏览器可以解决问题。我不知道为什么,但它有效。

    【讨论】:

      猜你喜欢
      • 2012-11-17
      • 2013-09-11
      • 2015-10-02
      • 2013-06-19
      相关资源
      最近更新 更多