设置自定义会话ID会导致脚本/ apache挂起

时间:2014-02-25 17:49:02

标签: php apache session curl sessionid

我正在构建一个单点登录系统,我正在使用cURL将请求发送到主站点上的文件并返回结果/他们的用户数据;但是,如果用户通过cookie登录到辅助站点(即;他们当前未登录到主站点),我需要确保他们同时登录主站点并设置一些会话变量,以便他们不必持续通过辅助站点上的cookie登录。

显然,我们通常会通过session id在我正在调用的文件上使用不同的cURL,因此设置任何$_SESSION变量都不会对辅助站点可用;所以我尝试通过session_id通过调用从辅助站点传递cURL然后在该文件中我这样做来设置会话ID,以便我在那里设置的任何$_SESSION变量可以访问辅助站点。

// Get session ID
$sid = trim($_GET['session_id']);

// Set the session id so we can get the added session data below via the forum
session_id($sid);

session_start();

然而,当我这样做并尝试访问辅助站点时,页面将无法加载,它只是挂起 - 我尝试删除该代码并再次加载它,但在重新启动Apache之前它不会加载。

顺便说一句..如果重要,这是在我的本地开发机器上,即Windows XP专业版。

任何想法!?

1 个答案:

答案 0 :(得分:2)

我假设你的主站点和辅助站点都在同一台服务器上并且使用相同的会话设置,特别是相同的session.save_path,这是正确的吗?
如果是这样,那就是你的问题所在:

PHP的默认会话处理机制使用文件来保存会话数据。

为了避免对会话文件的并发写访问,只要一个脚本(一个脚本实例更精确)仍在使用,该文件就会锁定会议。想要访问该特定会话的每个其他脚本都必须“等待”,直到第一个脚本完成使用该会话。

因此,当您尝试在辅助站点上使用主站点上已使用的会话ID启动会话时,由于该锁定,辅助站点上的脚本无法访问会话。
并且由于您的主站点的cURL请求正在等待辅助脚本完成,这本身仍在等待访问会话...您在这里遇到了一个很好的死锁: - )


您可以做的是,在发出cURL请求之前,在主站点脚本中调用session_write_close - 此时所有数据都写入会话文件,文件锁定为释放。

你必须要注意,在那之后你不能再在你的主站点脚本实例中使用会话 - 好吧,你仍然可以从$_SESSION数组中读取数据并将数据推送到{{1}}数组中,但是会话已经关闭,在该点之后您在该数组中更改的所有数据将不再保留。那么你在主脚本中对会话做了什么,然后关闭会话 - 然后发出你的cURL请求。


编辑嗯,请考虑一下 - 不确定上述内容是否真的有帮助...因为您的整个方法可能已经存在缺陷。在辅助站点上通过cURL调用脚本实际上不会在用户的浏览器中为您的辅助域设置会话cookie - 因为该辅助站点的脚本的每个响应都没有“登陆”在浏览器中,它登陆您的主站点脚本,因为这是您从中执行请求的地方。

我认为你真正需要的是从用户浏览器中的辅助站点调用脚本(JavaScript / AJAX请求,iframe,嵌入式图像),这样它就会设置一个会话名称和会话ID为您的辅助站点域下的值的cookie - 只有这样才能使PHP在导航到辅助站点后能够“识别”用户的浏览器。实际上打开会话将不是必需的(仍假设两个站点都使用相同的会话),因为会话已经启动,并且PHP需要它来挑选它在辅助站点上是来自cookie的匹配会话ID。

所以尝试这样做 - 但要注意你可能遇到的问题,因为浏览器会将辅助域的cookie视为第三方cookie 当您尝试在主站点的上下文中设置它时(并且域不匹配,例如,一个不在另一个的子域或类似的域上运行)。