我想我忘记了代码中的某些内容但找不到内容。
在我的服务器上,我有简单的logging.php
文件。
如果我传递user/password
个参数,则会创建一个新会话。
如果我通过loggout
会话被销毁。
如果我通过report
,则会在屏幕上报告当前会话变量列表。
如果我在浏览器中测试代码编写网址,那么一切正常。首先调用.../logging.php?user=xxx&password=xxx
。会话启动,会话变量报告给我。最后,我通过logout
参数销毁会话。
如果用户请求report
或logout
并且不存在会话,则会向客户端返回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并将其用于后续调用。
答案 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的会话被重新生成。