Я создал несколько веб-сайтов Django на одном домене:
Предполагается, что они полностью независимый — используются разными людьми для разных целей.
Однако файлы cookie, установленные пример.com, получают приоритет от Django, а значения, установленные site1.example.com, site2.example.com и т. д., игнорируются, если родительский домен установил файл cookie с тем же именем.
Когда загружается первая страница, он устанавливает файл cookie, чтобы сервер знал, что нужно отправить страницу компьютера или мобильную страницу со следующим запросом.
Программа Django создает правильную версию на основе значения файла cookie.
Когда site1.example.com загружается, он устанавливает файл cookie, запрашивающий мобильную версию. Но затем программа Django видит значение, установленное пример.com и игнорирует правильный файл 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 CSRF и не будет применяться к другим файлам cookie.
Как вы устанавливаете куки?
В качестве временного исправления я добавил код в свой функция setCookie:
var domain = window.location.hostname;
deleteParentCookieIfNecessary(name, domain);
удалитьParentCookieIfNecessary содержит:
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 родительского домена будет автоматически удален.
Поскольку вы говорите, что веб-сайты должны быть полностью независимыми, 3-е решение, которое вы предлагаете, кажется наиболее разумным. Вы не должны настраивать файлы cookie таким образом, чтобы они были доступны для субдоменов. В настоящее время вы указываете домен в файле cookie, вы должны пропустить домен, что будет означать, что файл cookie будет отправлен только для текущего домена (по крайней мере, в современных браузерах IE не следует этой спецификации). Если в файле cookie указан домен, это означает, что файл cookie также будет использоваться для субдоменов.
Как указано в RFC 6265 — раздел 4.1.2.3:
If the server omits the Domain attribute, the user agent will return the cookie only to the origin server.
Следовательно, ваша функция настройки файлов 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;
}
Отличный ответ. Можете ли вы добавить ссылку на ссылку?
@AndrewSwift добавил ссылку на RFC 6265.
Это помогает? docs.djangoproject.com/en/4.0/ref/settings/#csrf-cookie-domain