PHP会话和AJAX请求(来自注入的JS代码)

时间:2011-02-27 11:40:49

标签: php ajax session

我想我忘记了代码中的某些内容但找不到内容。

在我的服务器上,我有简单的logging.php文件。 如果我传递user/password个参数,则会创建一个新会话。 如果我通过loggout会话被销毁。 如果我通过report,则会在屏幕上报告当前会话变量列表。

如果我在浏览器中测试代码编写网址,那么一切正常。首先调用.../logging.php?user=xxx&password=xxx。会话启动,会话变量报告给我。最后,我通过logout参数销毁会话。

如果用户请求reportlogout并且不存在会话,则会向客户端返回HTTP-401错误代码。

另一方面,我有一段JavaScript代码,我可以使用bookmarklet在网页上注入。注入代码后,我会显示一个工具栏,用户可以在其中写入用户/密码并发送到服务器。

日志记录操作似乎工作正常,服务器返回200状态代码,但稍后如果我向logout发出请求,服务器会返回401错误,这意味着没有会话存在。

我正在使用chrome并查看HTTP请求,并且响应可以看到,当我记录服务器时,在响应中返回PHPSESSIONID的不同值。 这意味着两个不同的AJAX请求被视为不同的会话。服务器似乎无法识别来自AJAX的第二个请求,就好像它是由同一个客户端启动的一样。

重复一遍,如果我直接使用浏览器而不是AJAX请求执行,PHP代码工作正常,所以我想我忘记了AJAX中的内容。

有什么想法吗?

提前致谢。

更新

为了更简洁,我的问题是从JavaScript调用php。似乎没有会议开始。

想象一个非常简单的PHP代码:

  • logging.php:给定用户/密码启动新会话,并将“用户”名称存储为会话变量。

  • request.php:返回存储为会话变量的用户名。

  • logout.php:会破坏会话。

我的第一个AJAX请求启动了一个PHP会话。这似乎很好,因为从服务器返回PHPSESSIONID cookie。我还将用户名存储为会话变量。

第二个AJAX请求尝试获取用户名(存储在会话中),但它什么也得不到,此外还从服务器返回一个新的PHPSESSIONID cookie。

我知道这似乎是不可能的,当我使用浏览器网址请求进行测试时工作得很好,但这是事实。

我忘记了AJAX上的内容,过期时间或类似内容?

再次更新

我做了一些测试,但我发现了问题,但没有找到解决方案。

我的JS代码是通过书签注入的。 当我从我的服务器的HTML页面中注入代码时,AJAX请求工作正常。第一个(日志记录)请求获取PHPSESSID,该后续请求将传递给服务器。

另一方面,如果我加载google.com并注入代码,第一个(日志记录)请求也会获得PHPSESSID,但稍后它不会与下一个请求一起发送。

是否有人遇到过同样的问题?这是问题吗?

提前致谢。

再次更新

好吧最后我发现了我的问题。因为我的JS是从不同的域注入的(当前页面来自domainA而我的JS代码来自domainB),所以cookie不是跨域的,因此可以共享PHPSESSID。

可能的问题是,当我记录时,我将返回JSON数据中的PHP会话ID并将其用于后续调用。

3 个答案:

答案 0 :(得分:0)

如果我是正确的,您是否尝试通过向URL提供AJAX请求来登录用户,并在URL中提供用户名和密码?这不是一个真正安全的结构,密码很容易受到这种影响吗?!

我建议您实现jQuery,并使用$ .POST命令转发登录详细信息: http://api.jquery.com/jQuery.post/

确保所有文件(也是AJAX请求的文件)包含session_start();在文件顶部。 当每个文件都包含session_start();并且您使用相同的$ _SESSION变量来检查用户是否已登录,它应该可以工作!

答案 1 :(得分:0)

您的两个AJAX请求是否来自同一页面?请求是异步的,所以可能是“登录?”请求在“登录”请求通过之前返回其结果。

答案 2 :(得分:0)

根据您的要求,我希望您的代码(或多或少开头)类似于:

这样的文件logging.php:

<?php # file : loggging.php
if(!ini_set('session.auto_start')) 
// more stuff
if(!empty($_REQUEST['user']) && !empty($_REQUEST['passwd'])) {
    session_regenerate_sid(); // This is important (1)
    $_SESSION['user'] = $_REQUEST['user'];
    // Whatever
}

像这样的文件request.php ..

<?php # file : request.php
if(!ini_set('session.auto_start')) 
// Whatever stuff to process data
var_dump($_SESSION);
  // Or a nice foreach($v as $i => $x) {
  //    echo("[$i] => $x\n<br />");
  // } instead :)

你的logout.php读起来应该是......

<?php # file : logout.php
if(!ini_set('session.auto_start')) session_start();
session_destroy();

您可能没有调用session_start()或者您正在调用它两次。

要检查这一点,请尝试以下操作:更改所有session_start()行:

session_name('MYCoolNewName');
session_start();

现在,您的会话应该阅读PHPSESSID,而应该是MYCoolNewName

如果不是,那么你的问题就是前面提到的。

(1)我认为session_regenerate_sid()非常重要,因为打开认证会话是一种威胁。我将用一个例子来演示它。

Alice访问coolwebsite.com/login.php,这给了她一个我称之为AliceSID的SID。 Alice告诉Bob访问coolwebsite.com/login.php?PHPSESSID=AliceSID,当Bob做的时候,Alice可以登录他的帐户,除非Bob的会话被重新生成。