重定向到另一个域然后返回后丢失会话

Jos*_* Mc 4 php session facebook login session-variables

我正在创建一个登录系统,在该系统中我使用个人电子邮件地址作为我数据库中的唯一标识符。人们可以使用任何 openid 提供程序登录,例如 google ect(也可以是 facebook),它只会将电子邮件作为唯一标识符存储在我的 sql 数据库的用户表中。(意味着我不必担心电子邮件验证、密码等问题,用户不必注册)。

这是有效的,通过使用链接/javascript 打开一个新窗口,然后我的 php 脚本被定向到 google 或任何提供者。然后他们输入详细信息,然后 google/ect 会自动将窗口连同(如果有效)用户详细信息(最重要的是电子邮件)重定向回我的登录脚本。

现在我查看电子邮件的响应,看看它是否在我的数据库中,如果没有添加它,如果是,使用 $_SESSION,将用户登录到我的站点。

我使用 openid 机制(谷歌、雅虎等)完美地完成了这项工作。我也试图让它与 facebook 一起工作,但遇到了很大的困难。它能够将用户登录到 fb,获取用户电子邮件等。但是,一旦我尝试将用户登录到我的网站,它就不起作用。出于某种原因,它为我打开的新窗口(并且我的脚本 + 重定向运行)有一个单独的会话(包括单独的 sessionid),然后到我网站的其余部分?

只是想知道是否有人知道为什么会发生这种情况。

这是登录脚本的样子(在新窗口中运行):

<?php 

   $app_id = "YOUR_APP_ID";
   $app_secret = "YOUR_APP_SECRET";
   $my_url = "YOUR_URL";

   session_start();
   $code = $_REQUEST["code"];

   if(empty($code)) {
     $_SESSION['state'] = md5(uniqid(rand(), TRUE)); //CSRF protection
     $dialog_url = "https://www.facebook.com/dialog/oauth?client_id=" 
       . $app_id . "&redirect_uri=" . urlencode($my_url) . "&scope=email&state="
       . $_SESSION['state'];

     echo("<script> top.location.href='" . $dialog_url . "'</script>");
   }

   if($_REQUEST['state'] == $_SESSION['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);

     $graph_url = "https://graph.facebook.com/me?access_token=" 
       . $params['access_token'];

     $user = json_decode(file_get_contents($graph_url));
     echo("Hello " . $user->name);

     // try_register_or_login($user->email);

   }
   else {
     echo("The state does not match. You may be a victim of CSRF.");
   }

 ?>
Run Code Online (Sandbox Code Playgroud)

来源:https : //developers.facebook.com/docs/authentication/

我花了很多时间试图自己解决这个问题。任何帮助将非常感激。

小智 5

如果有人遇到这种情况并且不知道为什么或如何解决它:

我遇到了同样的问题。我的页面重定向到另一个站点,用户在那里做一些事情,这个站点将他重定向回我的站点,会话在这一步丢失了。问题出在我的 cookie 设置上。

我有以下 apache 指令:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict
Run Code Online (Sandbox Code Playgroud)

问题特别在于 SameSite=Strict 模式,因为 Strict 值阻止了任何跨站点使用的 cookie。

将值设置为 Lax:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Lax
Run Code Online (Sandbox Code Playgroud)

在不影响安全性的情况下解决了这个问题,因为 Lax 模式允许一些 GET 跨站点请求,只要是顶级请求。

每当地址栏中的 URL 由于此导航而更改时,都会发生顶级请求。iframe、图像或 XMLHttpRequests 不是这种情况。

参考:使用 samesite cookie 属性防止 CSRF


Mar*_*rty 3

我认为这个问题可能与跨域或 cookie 的设置方式有关。

对于跨域,请查看跨域 cookie

另一种可能性是使用 cookie 设置的标志。当我在 cookie 上设置安全标志,然后尝试通过非安全 (http) 页面访问它时,我遇到了这个确切的问题。另外,如果设置了 httponly 标志,则会导致 javascript 出现问题。您可以在http://www.php.net/manual/en/function.setcookie.php阅读有关这两个标志的信息