2012-01-21 36 views
8

我已经阅读了几个相关的帖子,但似乎无法使我的脚本按预期工作。php会话和iframe

我有一个用户登录的登录页面。如果密码匹配,脚本将两个值写入$_SESSION变量:['loggedin']='yes'['loginname']="username"

登录成功后,用户转到其中有2个iframe的另一个页面。

一个iframe使用外部内容并且不需要验证(从页面中删除此iframe不会更改任何内容)。

其他iframe使用来自同一个域的动态生成的内容,并检查会话变量是否仍然存在。

其中一个函数刷新动态生成的iframe的内容。

一旦完成,会话变量将丢失。事实上,会议本身不再存在。

我在与此脚本有关的每个页面上都有session_start();

任何帮助将不胜感激。

+0

如果您在iframes页面上有session_start(),则应该没有问题。 – Chibuzo

+0

我有一个基于cookie的会话在我的iframe中不工作的问题。这是因为我正在测试的浏览器已禁用**第三方Cookie。 –

回答

4

以下内容添加到您的每个网页的框架:

echo "Session ID: ".session_id();

这应该在每一页上输出的会话ID。可能会在其中一个框架上生成一个新的会话,通过检查上述内容,您可以排除这种可能性。

+0

好的,我添加了该行,结果令我晕眩。 session_id是相同的,但是不知怎的,脚本没有通过if($ _SESSION)条件。所以我有这样的代码:'if(!$ _ SESSION){echo“no session”; echo session_id(); }'。令人惊讶的是,我得到以下输出:“no sessionSession ID:2c49b03084d3a5112e332e0d53008650”在正常情况下,“无会话”代码触发用户回到验证阶段。 $ _SESSION var是如何可能是空的,但仍然有会话ID? –

+1

尝试'如果(!isset($ _ SESSION))' –

+0

哇,这是尴尬。 isset固定条件。但我仍然有消失的变量的问题,因为现在它失败了其他条件:'if(($ _SESSION ['AdminLoggedIn']!=“YES”)||($ _SESSION ['AdminName'] ==“” )){' –

16

我相信这article'll有用: http://www.how2guru.com/archives/php-session-problem-while-using-iframe/

简短的回答是:在iframe中,像这样开头的会议:

header('P3P: CP="CAO PSA OUR"'); 
session_start(); 

编辑:

思想我应该更新这个答案,因为我偶然发现了每个人都应该知道的有趣事情。

此p3p标头破解不适用于safari

下面我描述了我的登录流程,以及我如何解决这个问题。

我的登录流程看起来像这样(页面应用程序):

  • 检查当前用户会话,
  • 如果不是,重定向到登录URL(由PHP SDK生成),
  • 登录对话框重定向回一个url,我使用'code'GET参数Facebook给我,得到一个访问令牌,我可以存储它以备将来使用。 (保存到会话的数据库)。如果我完成了这个工作,我将用户重定向到我的页面应用程序,在那里一切都会工作。
  • 此时大家都应该高兴。

但是这里来了一个问题。

如果用户使用Safari浏览器,并尝试打开该应用程序时,会议早已见怪不怪(几天后的前)被破坏,下面的事情发生:

  • 的代码检查会话:它找到用户ID(PHP SDK的getUser()方法),所以我首先检查数据库中的条目。
  • 由于用户之前登录过,他在数据库中有一个条目,所以我只抓住它并将它保存到一个会话中,这样未来的AJAX调用将拥有他们需要的所有信息。

这里需要注意的重要一点是,此代码在iframe中的页面选项卡中运行。

因此,对于大多数用户来说,由于p3p标头破解,代码将起作用。

但是对于safari用户来说,它不会。

Safari不关心给定标,它拒绝保存会话,因此该应用程式的用户登录,一切似乎都做工精细,但AJAX调用不会起作用,因为他们赢得了”没有任何会议可以使用。

解决方法:

很其实很简单 - 虽然不太优雅,但嘿,它的工作原理。 - :我检查客户端浏览器是否是Safari浏览器,如果是,我重定向到自定义网址,我在其中启动会话 - 在facebook iframe之外 - 然后重定向回应用程序。

这将创建没有问题的cookie,因此会话将可用。

在这里,有一些代码:

  • 检查会议 (Credit goes to this guy)

    if (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') && !strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome')) { 
        if (count($_COOKIE) === 0) { 
        echo '<script> 
        top.location = "http://www.domain.com/setcookie.php"; 
        </script>'; 
        } 
    } 
    
  • 设置会话(setcookie.php)

    header('P3P: CP="CAO PSA OUR"'); 
    session_start(); 
    $_SESSION = array(); 
    
    echo 
    '<script> 
    top.location = "http://back-to-the-facebook-app.com"; 
    </script>'; 
    

我希望这个额外的技巧将有助于某人。

EDIT2

我没有尝试这一个还没有,但不是添加的P3P头,你可以只添加以下行到你。htaccess的:

<IfModule mod_headers.c> 
    Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" 
</IfModule> 

搭配点评:

# ------------------------------------------------------------------------------ 
# | Cookie setting from iframes            | 
# ------------------------------------------------------------------------------ 

# Allow cookies to be set from iframes in IE. 
# http://msdn.microsoft.com/en-us/library/ms537343.aspx 
# http://www.w3.org/TR/2000/CR-P3P-20001215/ 

<IfModule mod_headers.c> 
    Header set P3P "policyref=\"/w3c/p3p.xml\", CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"" 
</IfModule> 

一切归功于此为Yeoman项目背后的家伙.htacces代码。

+1

对于http /服务器/位置块中的nginx add add_header P3P'policyref =“/ w3c/p3p.xml”,CP =“ IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT“,CP =”CAO PSA OUR“'; –

+0

Saulius - 这个工作是否也适用于safari?对我来说它没有帮助,或者我做错了什么 –