Cookies 从ajax请求在子域上设置cookie

Cookies 从ajax请求在子域上设置cookie,cookies,subdomain,Cookies,Subdomain,我在www.example.com上有一个webapp,在API.example.com上有一个API webapp对API进行ajax调用 我需要在api.example.com上放一个cookie来跟踪会话 为了跟踪我的问题,我在webapp和api的两个子域上都设置了测试cookie。 webapp在.example.com上设置了一个cookie,api在.example.com上设置了一个cookie,在api.example.com上设置了另一个cookie。 Cookie仅使用Do

我在www.example.com上有一个webapp,在API.example.com上有一个API

webapp对API进行ajax调用

我需要在api.example.com上放一个cookie来跟踪会话

为了跟踪我的问题,我在webapp和api的两个子域上都设置了测试cookie。 webapp在.example.com上设置了一个cookie,api在.example.com上设置了一个cookie,在api.example.com上设置了另一个cookie。 Cookie仅使用Domain=.example.com设置。没有路径,没有HTTPOnly

注意:最后我只需要一个api.example.com。但这些都是为了测试

使用my browser(Firefox 16)进行直接查询很好。 api查询:设置并发送两个cookie。 www上的查询:设置cookie并发送api中的两个cookie。(当然,前提是我在api之后查询www)

现在,我只清理浏览器cookies和查询www。 在www上查询:工作正常,和以前一样。 来自www的ajax请求的api子查询:不发送cookie。设置Cookies不起任何作用。使用Firebug,我在响应中看到cookies。但在随后的请求或页面信息中没有它们的痕迹

我尝试在Firefox上启用Cookie日志。绝对并没有来自api的cookies痕迹,甚至并没有拒绝通知

最后,我只需要一种在api上存储一个cookie的方法。为此,我非常开放:)

资料: 这两台服务器是NodeJS。 我尝试使用firebug在服务器端(设置cookie头)和客户端(document.cookies)手动设置cookie

我检查过的其他帖子没有解决方案(还有许多我不记得的帖子):

在api上设置允许凭据标头 对请求使用带有凭据的
否则,
XMLHttpRequest
发送cookie,而不管
访问控制允许凭据
头如何

删除
访问控制允许原点上的通配符
通配符
*
将不起作用。如果设置了
withCredentials
,浏览器将放弃响应

参考资料:


除了Alexandre的正确答案之外,这是我通过.htaccess进行的CORS设置

添加到api.example.com上带有phps(或更高版本)目录的.htaccess文件中:

其中URL在api.example.com上调用php

请注意,Alexandre是对的,您必须指定一个确切的子域,不幸的是,任何通配符都无法工作。所以这是行不通的:

Header set Access-Control-Allow-Origin "*"

当使用Access Control Allow Credentials“true”设置时,CORS将阻止此设置。

当我需要使用AJAX和PHP将Cookie从多个子域传递到单个API域时,我在后面添加了此帖子,因为我以前的解决方案遇到了问题

这就是挑战和解决方案:

1-api.example.com上的后端PHP

2-多个JS前端,如one.example.com、two.example.com等

3-Cookie需要双向传递

4-在api.example.com上从多个前端到PHP后端的AJAX调用

5-在PHP中,我不喜欢使用$_SERVER[“HTTP_ORIGIN”],在我看来并不总是可靠/安全的(我有一些浏览器HTTP-ORIGIN总是空的)

在具有单个前端域的PHP中执行此操作的常规方法是使用以下代码启动PHP代码:

header('Access-Control-Allow-Origin: https://one.example.com');  
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');  
header('Access-Control-Allow-Credentials: true');  
在one.example.com域的JS中:

jQuery.ajax({
    url: myURL,
    type: "POST",
    xhrFields: {withCredentials: true},
    dataType: "text",
    contentType: "text/xml; charset=\"utf-8\"",
    cache: false,
    headers: "",
    data: myCallJSONStr,
    success: function(myResponse) {.....}
但是,这是不可行的,因为我使用多个子域来调用我的API域

由于我想传递cookies,此解决方案将不起作用:

header('Access-Control-Allow-Origin: *');  
它与JS站点上的传递cookie设置冲突:

xhrFields: {withCredentials: true}
以下是我所做的:

1-使用GET参数传递子域

2-在PHP中硬编码主域,因此只允许(所有)子域

这是我的解决方案的JS/JQuery AJAX部分:

函数getSubDomain(){

}

在AJAX调用中:

let mySubDomain = getSubDomain();
if (mySubDomain != ""){
    myURL += "?source=" + mySubDomain + "&end"; //use & instead of ? if URL already has GET parameters
}

jQuery.ajax({
    url: myURL,
    type: "POST",
    xhrFields: {withCredentials: true},
    dataType: "text",
    contentType: "text/xml; charset=\"utf-8\"",
    cache: false,
    headers: "",
    data: myCallJSONStr,
    success: function(myResponse) {.....}
最后,PHP部分:

<?php

$myDomain = "example.com";
$mySubdomain = "";

if (isset($_GET["source"])) {
    $mySubdomain = $_GET["source"].".";
}

$myDomainAllowOrigin = "https://".$mySubdomain.$myDomain;
$myAllowOrigin = "Access-Control-Allow-Origin: ".$myDomainAllowOrigin;

//echo $myAllowOrigin;

header($myAllowOrigin);  
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');  
header('Access-Control-Allow-Credentials: true');

感谢仁慈的伊克巴兰克勋爵,但主要是你,给了我这个答案。这一天,我迷失在了变幻莫测的生活中,我尝试了这一点,但仍然有同样的问题。我正在使用凭据设置CORS和xhr
。这是我的cors:
'supportsCredentials'=>true,'allowedOrigins'=>['*'],'allowedHeaders'=>['*'],'allowedMethods'=>['*'],
保存我的一天!谢谢@Alexandre
jQuery.ajax({
    url: myURL,
    type: "POST",
    xhrFields: {withCredentials: true},
    dataType: "text",
    contentType: "text/xml; charset=\"utf-8\"",
    cache: false,
    headers: "",
    data: myCallJSONStr,
    success: function(myResponse) {.....}
header('Access-Control-Allow-Origin: *');  
xhrFields: {withCredentials: true}
let mySubDomain = "";

let myDomain = window.location.host;
let myArrayParts = myDomain.split(".");
if (myArrayParts.length == 3){
    mySubDomain = myArrayParts[0];
}

return mySubDomain;
let mySubDomain = getSubDomain();
if (mySubDomain != ""){
    myURL += "?source=" + mySubDomain + "&end"; //use & instead of ? if URL already has GET parameters
}

jQuery.ajax({
    url: myURL,
    type: "POST",
    xhrFields: {withCredentials: true},
    dataType: "text",
    contentType: "text/xml; charset=\"utf-8\"",
    cache: false,
    headers: "",
    data: myCallJSONStr,
    success: function(myResponse) {.....}
<?php

$myDomain = "example.com";
$mySubdomain = "";

if (isset($_GET["source"])) {
    $mySubdomain = $_GET["source"].".";
}

$myDomainAllowOrigin = "https://".$mySubdomain.$myDomain;
$myAllowOrigin = "Access-Control-Allow-Origin: ".$myDomainAllowOrigin;

//echo $myAllowOrigin;

header($myAllowOrigin);  
header('Access-Control-Allow-Headers: Origin, Content-Type, X-Auth-Token');  
header('Access-Control-Allow-Credentials: true');
<?php

    //////////////// GLOBALS /////////////////////////////////
    
    $gCookieDomain = ".example.com";
    $gCookieValidForDays = 90;
    
    //////////////// COOKIE FUNTIONS /////////////////////////////////
    
    function setAPCookie($myCookieName, $myCookieValue, $myHttponly){
        global $gCookieDomain;
        global $gCookieValidForDays;
        
        $myExpires = time()+60*60*24*$gCookieValidForDays;
        setcookie($myCookieName, $myCookieValue, $myExpires, "/", $gCookieDomain, true, $myHttponly);   
        
        return $myExpires;
    }
<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "https://one.example.com"
    Header set Access-Control-Allow-Headers "Origin, Content-Type, X-Auth-Token"
    Header set Access-Control-Allow-Credentials "true"
</IfModule>