首先,有关项目的一些信息
这个问题发生在我用php开发的网站上。我们决定为我们的JSON api使用不同的子域:
我们所在的子域名:tickets.example.com JSON位置:api.example.com/json
为了登录我们正在开发的故障单系统,我们向php脚本发送一个get请求,该结果将结果作为json-string返回。
问题
当我们向登录脚本发送请求时,似乎php无法看到我们已经创建了会话。虽然我们已经设置了PHPSESSID cookie,但由于某种原因我在响应头中获得了一个新的会话ID。
你可以说“嘿,不同的子域。当然它不会起作用!”
我自己会想到这一点,但是使用cookie编辑器将会话ID更改为响应中Set-cookie标头中的会话ID会让我进入。
数据流
缺乏更好的名字
步骤1:请求通过jquery发送,如下所示:
$('#loginForm').submit( function(e) {
e.preventDefault();
$.post( 'http://api.website.com/json/login.php', $('#loginForm').serialize(), function(data) {
if(data.result==true)
{
location.reload();
}
else
{
error(data.message);
}
},
'json'
);
});
正如您所看到的,如果我们在json文件中得到result = true,则网站应该重新加载(并显示登录的站点)。发生这种情况,但由于会话处理中出现了问题,我们将设置为“登录”另一个会话ID。
这是请求sendt和响应头:
image http://puu.sh/anKCX/75701a8891.png
正如您所看到的,我们获得了一个Set-cookie标头,告诉我们将Cookie PHPSESSID设置为某些内容。这实际上从未实现,并且cookie与登录前保持一致(r71qijt6utua4qjgarm59oe535)
如我所述,将cookie更改为我们的新会话ID会让我们进入。
代码
以下是一些片段:
的login.php
<?php
require_once 'utils.php'; //Runs session_start();
[...]
if (!Utils::isAuthenticated()) {
if (isset($_POST['username']) &&
isset($_POST['password']) &&
!empty($_POST['username']) &&
!empty($_POST['password'])) {
$username = $_POST['username'];
$password = hash('sha256', $_POST['password']);
if (UserHandler::userExists($username)) {
$user = UserHandler::getUserByName($username);
$storedPassword = $user->getPassword();
if ($password == $storedPassword) {
$_SESSION['user'] = $user;
[...]
答案 0 :(得分:0)
我认为你正在寻找session_set_cookie_params
。根据文档这个功能:
设置php.ini文件中定义的cookie参数。此功能的效果仅持续脚本的持续时间。因此,您需要在调用session_start()之前为每个请求调用session_set_cookie_params()。
此函数更新相应PHP ini配置键的运行时ini值,可以使用ini_get()检索。
通过指定.example.com
而不是exchange.example.com
或api.example.com
,您可以创建一个可在所有子域中使用的通配符cookie。 0
表示这是一个会话cookie,它将在浏览会话结束时到期(例如浏览器关闭时),/
这里只指定cookie设置在根目录你的网站。
session_set_cookie_params(0, '/', '.example.com');
session_start();
参考: session_set_cookie_params(...);
注意:确保在致电session_set_cookie_params(...);
之前放置session_start();
,因为它引用了您正在设置的值。如果您在session_start();
之后放置它,则会在设置会话cookie之后更新值,从而无法运行此功能。