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

时间:2011-07-17 08:18:20

标签: php facebook session login session-variables

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

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

现在在回复中我查看了电子邮件,看看它是否在我的数据库中,如果没有添加它,如果是这样,使用$ _SESSION,将用户登录到我的网站。

我使用openid机制(google,yahoo,ect)完美地工作。我试图让它与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.");
   }

 ?>

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

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

3 个答案:

答案 0 :(得分:3)

我认为这个问题可能与跨域或可能如何设置cookie有关。

要跨域,请查看Cross domain cookies

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

了解这两个标志

答案 1 :(得分:1)

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

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

我有以下apache指令:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Strict

问题特别是在SameSite = Strict模式下出现,因为Strict值会阻止cookie跨站点使用。

将值设置为Lax:

Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure;SameSite=Lax

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

  

只要地址栏中的URL发生更改,就会发生顶级请求   因为这个导航。对于iframe,图片则不是这种情况   或XMLHttpRequests。

参考:Preventing CSRF with samesite cookie attribute

答案 2 :(得分:0)

Asp.net:-

注意:-您由于以下原因而遇到此问题:- Plz click the URL to know the issue

在浏览器中显示您的唯一sessionId的“ SameSite”是否显示不佳:- Click here to see

答案:-

1)在Web.config文件中添加以下代码

    <system.web> 
     <sessionState cookieless="false" cookieSameSite="None"/>
   <system.web>

2)需要从浏览器中删除cookie(我们至少需要删除一次cookie)

a)手动执行 要么 b)在globle.aspx中使用以下代码

private void Session_Start(object sender, EventArgs e)
    {
         if (HttpContext.Current != null)
        {
            int cookieCount = HttpContext.Current.Request.Cookies.Count;
            for (var i = 0; i < cookieCount; i++)
            {
                var cookie = HttpContext.Current.Request.Cookies[i];
                if (cookie != null)
                {
                    var expiredCookie = new HttpCookie(cookie.Name)
                    {
                        Expires = DateTime.Now.AddDays(-1),
                        Domain = cookie.Domain
                    };
                    HttpContext.Current.Response.Cookies.Add(expiredCookie); // overwrite it
                }
            }

            // clear cookies server side
            HttpContext.Current.Request.Cookies.Clear();
        }
    } 

3)现在,您的浏览器sessionId的“相同站点”显示“无”:-

click here to see

它在asp.net网络应用程序中为我工作。