AJAX请求是否保留PHP会话信息?


154

如果我有一个用户登录到我的网站,并将其ID存储在中$_SESSION,则从他的浏览器中单击“保存”按钮,该按钮将向服务器发出AJAX请求。将他$_SESSION和饼干被保留在该请求,我可以安全地依赖存在于该ID $_SESSION

Answers:


191

答案是肯定的:

会话在服务器端维护。就服务器而言,AJAX请求和常规页面请求之间没有区别。它们都是HTTP请求,并且都以相同的方式在标头中包含cookie信息。

无论是常规请求还是AJAX请求,都将从客户端将相同的Cookie始终发送到服务器。Javascript代码不需要做任何特殊的事情,甚至不需要了解这种情况,它的工作原理与常规请求相同。


10
后续:服务器可以HttpOnly在设置cookie时设置一个标志,这意味着您的Javascript将无法看到该cookie。然而该cookie 仍然是这两个AJAX和普通页面请求被发送,并继续工作完全一样。您的Javascript不会在中显示document.cookie
thomasrutter

如果打开了PHP错误报告,则可以获得AJAX响应返回的会话错误。我Warning: session_write_close(): Failed to write session data (user)最近在项目中间歇性地收到一个错误,但仅在页面其余部分的加载期间发生AJAX请求时才出现。我正在使用MySQL数据库存储会话数据,并且主页请求可能锁定了该表,从而阻止了AJAX请求对其进行访问。
Buttle Butkus

@ButtleButkus在您的服务器端代码中听起来像是一个问题,如果您将其作为自己的问题提交,我敢肯定人们会愿意提供帮助。您不应该仅仅因为正在使用MySQL进行会话而得到该错误,因为它不应以会因错误而失败的方式锁定。MySQL连接饱和可能是一个问题,或者是其他一些不相关的问题。
thomasrutter

它在无所事事的机器上发生,因此MySQL连接应该处于饱和状态。我一定会提出一个问题,如果我不能很快解决。
Buttle Butkus

23

如果PHP文件中的AJAX请求具有session_start()会话信息,则将保留该信息。(禁止请求在同一域内)


2
的确,那就是我忘了做的事:-)
sivann 2012年

23

您真正要了解的是:cookie是否随AJAX请求一起发送?假设AJAX请求针对同一个域(或在cookie的域约束内),则答案为是。因此,返回给同一服务器的AJAX请求确实保留了相同的会话信息(假设被调用的脚本与希望访问会话信息的任何其他PHP脚本一样发出一个session_start())。


1
我可能是错的,但我认为甚至无法将Ajax请求发布到其他域(不包括子域)吗?
Emil H

您也许可以通过动态脚本技巧来作弊。永远不要累。
cletus

1
是的,无法向其他域发出ajax请求。但是,您可以在页面中动态插入一个<script>标记,并将其src设置为回显javascript的域外网址。
点击Upvote 09年

1
无法向其他域发出ajax请求。但您可以在您的php代码中创建代理。ajax请求到代理,代理请求到其他域。
彼得·朗

2
请注意...可以跨域提出ajax请求,但前提是响应类型为jsonp。我一直都这样做。
主显节2012年

8

好吧,并非总是如此。使用cookie,您感觉很好。但是“我可以安全地依赖于存在的id”敦促我扩大讨论的重点(主要是供参考,因为此页面的访问者数量似乎很高)。

可以将PHP配置为通过URL重写而不是cookie来维护会话。它的好坏(<-参见此处的最高注释)是一个单独的问题,让我们继续讨论当前的问题,仅附带一个注解:基于URL的会话最突出的问题-公然裸会话ID的可见性-内部Ajax调用不是问题;但是,如果为Ajax启用了该功能,那么其​​余站点也已启用了该功能,因此...)

在进行URL重写(无cookie)会话的情况下,Ajax调用必须自己处理好它们的请求URL。(或者,您可以推出自己的自定义解决方案。在要求不高的情况下,您甚至可以求助于在客户端维护会话。)重点是,如果不使用cookie,则会话连续性需要明确的注意

  1. 如果Ajax调用只是从HTML中逐字提取 URL(从PHP接收),那应该可以,因为它们已经被煮熟了(嗯,煮熟了)。

  2. 如果他们需要自己组装请求URI,则需要将会话ID手动添加到URL。(检查此处,或PHP生成的页面源(启用URL重写),以了解如何执行此操作。)


来自OWASP.org

有效地,如果满足某些条件(例如,存在不支持Cookie的Web客户端或不支持Cookie的情况),则Web应用程序可以同时使用Cookie,URL参数或机制,甚至可以从一种切换到另一种(自动URL重写)。由于用户隐私问题而被接受)。

Ruby论坛中

当使用带有cookie的php时,即使对于Ajax XMLHttpRequests,会话ID也会自动在请求标头中发送。 如果使用或允许基于URL的php会话,则必须将会话ID添加到每个Ajax请求url。


关于禁用会话 Cookie的人数的可靠统计信息吗?(我找不到任何内容。仅使用Javascript:在美国/欧洲大约占2%,世界平均水平约为1.2%。)
Sz。

URL上的会话ID是一种过时的,不安全的做法。在当今的网络上,没有人会假设他们可以在禁用cookie的情况下进行浏览,而仍然登录到拥有帐户的网站。如果您的访问者之一禁用了Cookie,则可以安全地假定以下两种情况之一:a)他们出于隐私原因明确不想在任何网站上登录;或b)他们无意中这样做了,现在他们无法登录任何站点,而不仅仅是您的站点。
thomasrutter

3

AJAX请求保留会话非常重要。最简单的例子是,当您尝试对管理面板进行AJAX请求时,可以说。当然,您将保护您向其发出请求的页面,而不被管理员登录后没有会话的其他人访问。说得通?


0

不过,需要注意的一件事是检查应用程序是否在请求之间重新生成会话ID,特别是如果您使用的是框架-明确依赖于会话ID的任何内容都会遇到问题,尽管显然其中的其余数据该会话将不受影响。

如果应用程序正在像这样重新生成会话ID,那么您可能会遇到这样的情况,即ajax请求实际上会无效/替换请求页面中的会话ID。


0

框架就是这样做的,例如,如果您在Front Controller或boostrap脚本中初始化会话,则不必担心页面控制器或Ajax控制器的初始化。PHP框架不是万能的,但是它们可以做很多有用的事情!


0

将您的session()auth放在接受ajax请求的所有服务器端页面中:

if(require_once("auth.php")) {

//run json code

}

// do nothing otherwise

那是我做过的唯一方法。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.