Cookie冲突:Django和Javascript中是否可以区分父域和子域Cookie



我在一个域上建立了一堆Django网站:

  • example.com
  • site1.example.com
  • site2.example.com
  • site3.example.com

它们应该是完全独立的——被不同的人用于不同的目的。

但是,Django会优先考虑example.com设置的cookie,如果父域设置了同名cookie,则会忽略site1.example.comsite2.example.com


工作原理:

当加载第一个页面时,它会设置一个cookie,以便服务器知道下一个请求是发送计算机页面还是移动页面。

Django程序基于cookie值构建正确的版本。

site1.example.com加载时,它会设置一个请求移动版本的cookie。但是Django程序看到example.com设置的值,并且忽略正确的cookie

因此,我需要一种方法来完成以下操作之一:

  1. 阻止site1.example.com读取example.com的cookie
  2. 区分Django中与cookie相关联的域,这样我就可以判断该值是错误的
  3. 找到一种方法在Javascript中设置父域cookie,使其对子域不可访问(我不使用www(

如果我找不到一个优雅的解决方案,我可能会更改cookie名称,使其随域名而变化。

我知道我可以使用会话框架,但除了这个特定的问题之外,一切都很好。我真的很想避免修改我现有的系统,尽管如果必须的话,我会的

[更新]这是cookie设置功能:

function setCookie(cname, cvalue, exdays) {
var domain = window.location.hostname;

if (exdays > 7) exdays = 7; // max in Safari
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var name = cname + '=' + cvalue + '; ';
var expy = 'expires=' + d.toUTCString(); + '; ';
var domn = '; domain=' + domain + '; ';
var path = 'path=/; ';
var secu = 'samesite=lax; secure;';
var complete = name + expy + domn + path + secu;
document.cookie = complete;
}

既然你说网站应该是完全独立的,那么你提出的第三种解决方案似乎是最明智的。您不应该以子域可访问的方式设置cookie。当前您正在cookie中指定域,您应该跳过该域,这意味着cookie将只发送给当前域(至少在现代浏览器中,IE不遵循此规范(。如果在cookie中指定了域,则意味着该cookie也将用于子域。

如RFC 6265第4.1.2.3节所述:

如果服务器省略了Domain属性,则用户代理将返回cookie仅发送到原始服务器。

因此,您的cookie设置功能应该如下所示:

function setCookie(cname, cvalue, exdays) {
// Domain should not be set unless cookie needs to be accessed by subdomains
// var domain = window.location.hostname;

if (exdays > 7) exdays = 7; // max in Safari
var d = new Date();
d.setTime(d.getTime() + (exdays*24*60*60*1000));
var name = cname + '=' + cvalue + '; ';
var expy = 'expires=' + d.toUTCString(); + '; ';
// Domain should not be set unless cookie needs to be accessed by subdomains
// var domn = '; domain=' + domain + '; ';
var path = 'path=/; ';
var secu = 'samesite=lax; secure;';
var complete = name + expy + path + secu;
document.cookie = complete;
}

作为临时修复,我向我的setCookie函数添加了一些代码:

var domain = window.location.hostname;
deleteParentCookieIfNecessary(name, domain);

deleteParentCookieIfNenecessary包含:

function deleteParentCookieIfNecessary(name, domain){
var parts = domain.split('.');
if (parts.length > 2){ // on subdomain
var domain = parts.slice(-2).join('.');
document.cookie = cname + '=;domain=.' + domain + ';path=/;max-age=0';
}
}

结果是当cookie设置为时,如果url是子域,则父域的同名cookie将自动删除

最新更新