我在这里阅读了几个相关的帖子,但似乎无法使我的脚本按预期工作。
我有一个用户登录的登录页面。如果密码匹配,脚本会将两个值写入$_SESSION
变量:['loggedin']='yes'
和['loginname']="username"
。
成功登录后,用户会转到另一个包含2个iframe的网页。
一个iframe使用外部内容,不需要身份验证(从页面中删除此iframe不会改变任何内容)。
另一个iframe使用来自同一域的动态生成的内容,并检查会话变量是否仍在那里。
其中一个功能刷新动态生成的iframe的内容。
完成此操作后,会话变量将丢失。事实上,会话本身已不复存在。
我在与此脚本相关的每个页面上都有session_start();
。
非常感谢任何帮助。
答案 0 :(得分:16)
我相信这篇文章会很有用: http://www.how2guru.com/archives/php-session-problem-while-using-iframe/
简短的回答是:在iframe中,像这样开始会话:
header('P3P: CP="CAO PSA OUR"');
session_start();
修改强>
我想我应该更新这个答案,因为我偶然发现了每个人都应该知道的有趣事情。
此p3p标头黑客无法在Safari中使用。
下面我描述我的登录流程,以及我如何解决这个问题。
我的登录流程如下(页面应用程序):
但这里有问题。
如果用户使用safari,并且在会话已经被销毁时尝试打开此应用程序(几天后会被解雇),则会发生以下情况:
这里需要注意的重要一点是,此代码在iframe的页面标签中运行。
因此,对于大多数用户而言,代码将起作用,因为p3p头部黑客攻击。
但对于safari用户来说,它不会。
Safari不关心给定的标题,它拒绝保存会话,因此用户登录到应用程序,一切似乎都运行正常,但是ajax调用不起作用,因为它们不会有任何与之合作的会议。
解决方法:
实际上非常简单 - 虽然不是太优雅,但嘿,它的确有效。 - :我检查客户端浏览器是否是safari,如果是,我会重定向到自定义URL,在那里我开始会话 - 在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 强>
我还没试过这个,但是你可以在你的.htaccess中添加以下几行,而不是添加P3P标题:
<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 :(得分:4)
将以下内容添加到框架中的每个页面:
echo "Session ID: ".session_id();
这应该在每个页面上输出会话ID。有可能在其中一个帧上生成一个新会话,通过检查上面你可以排除这种可能性。