我正在尝试使用ajax设置登录系统。
用户在subdomain.domain.com(也可能是otherdomain.com)中插入登录名和密码后,我向rest.domain.com发出Jquery $ .post请求,用户正确登录。
然后,如果我向rest.domain.com发出另一个请求以检查用户是否已登录(或进行其他需要用户登录的操作),则会话为空。
我做错了什么?
修改
客户端应用
$.post('http://rest.domain.com/user/login',form,function(data){
//Do what is needed
});
RESTful app(使用Slim和uFlex)
header('Access-Control-Allow-Origin: *');
session_start();
//User
//Check if logged
$app->get('/user/logged', function () use ($user, $app){
print_r($_SESSION);
echo $user->signed;
});
//Login
$app->post('/user/login', function () use ($user, $app) {
$username = isset($_POST['email']) ? $_POST['email'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;
$auto = isset($_POST['auto']) ? $_POST['auto'] : false;
$user->login($username,$password,$auto);
if($user->signed){
print_r($_SESSION);
}else{
//Display Errors
foreach($user->error() as $err){
echo "<b>Error:</b> {$err} <br/ >";
}
}
});
答案 0 :(得分:2)
我认为你违反了同源政策。您不能向不同的域发出Ajax请求,或者至少是SOP规定的那些请求。所以这是你应该看的东西。
执行上述步骤后,使用浏览器检查存储的Cookie。 Cookie是按子域存储的,因此您的PHP_SESSID
Cookie(如果您使用的是$_SESSION
)可能存在于错误的子域中。
您能否提供有关如何存储会话的更多信息?
无论上述情况如何,最好将所有Ajax请求指向同一子域,协议等的相同目标ajax.php
文件。(SOP的所有规则)并将请求路由到服务器级别。
答案 1 :(得分:0)
您的会话可能存储在与rest.domain.com绑定的Cookie中。
看到这个帖子: Why is jquery's .ajax() method not sending my session cookie?
为了支持这种身份验证,您可以在同一个域中同时拥有REST API和Web站点,也可以根据客户端和服务器之间交换的标头(可以控制)定义会话身份验证
例如,在执行初始身份验证后,您可以生成随机会话ID(不是PHP会话ID)和next-request-id,并通过HTTP标头将其发送回客户端。
客户端您将读取session-id和next-request-id,并将其用于对REST API的后续请求。
REST API将检查session-id和next-request-id并验证它。如果有效,则对请求进行身份验证。在响应中,相同的session-id和新的next-request-id被发送回客户端。
为了避免第三方篡改会话,如果使用了两次request-id,则session-id应该无效。
为了在页面更改中重用会话ID,您可以将它们存储在浏览器localStorage中。
答案 2 :(得分:0)
虽然完全可以制作跨域ajax请求,但出于安全原因,这些请求不会设置必要的cookie来保持有效会话。
在我的情况下,软件设计允许我删除所有跨域请求并替换它们以使其工作。
如果情况并非如此,我认为最好的解决方案是依靠OAuth作为大多数“严肃”的RESTful apis。