#python #google-chrome #nginx #cookies #flask
#python #google-chrome #nginx #файлы cookie #flask
Вопрос:
У меня есть следующие поддомены:
api.example.com
app1.example.com
app2.example.com
Я использую nginx в качестве веб-сервера для обслуживания всего этого. api.example.com
это приложение на python-flask, которое я разрабатываю. app1.example.com
и app2.example.com
являются статическим контентом js, разработанным не мной.
Nginx настроен так, чтобы разрешить совместное использование ресурсов из разных источников:
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Max-Age' 1728000 always;
add_header 'Content-Type' 'text/plain; charset=utf-8' always;
add_header 'Content-Length' 0 always;
return 204;
}
if ($request_method = 'POST') {
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
if ($request_method = 'GET') {
add_header 'Access-Control-Allow-Origin' $http_origin always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
add_header 'Access-Control-Allow-Credentials' 'true' always;
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always;
}
Выше приведен location
блок, который передает управление сокету uwsgi. То же самое копируется для api1
и api2
.
app1
и app2
делают запросы к api
, и api
устанавливает cookie в ответ на некоторые из этих запросов.
Файлы cookie устанавливаются следующим образом:
response.set_cookie(
key='some_cookie_name',
value=some_token,
max_age=current_app.config["JWT_EXP"],
secure=True,
httponly=True)
path
по умолчанию установлено значение '/'
,
domain
атрибут отсутствует в ответе, samesite
атрибут также отсутствует,
все вышеописанное в соответствии с этой документацией.
Поправьте меня, если я ошибаюсь, но, насколько я понимаю, когда app1
запрашивает api
ресурс (который устанавливает cookie), этот cookie ограничен app1.example.com
и не должен присутствовать на app2.example.com
(и наоборот).
Поведение, которое я наблюдаю в Chrome, отличается.
Установка cookie по app1
запросу, а затем установка cookie (с тем же именем) по app2
запросу переопределяет cookie на app1
. app2
на поддомене отсутствуют cookie-файлы (проверка с помощью инструментов разработчика Chrome).
Теперь, когда я меняю имя cookie для второго поддомена ( app2
), cookie-файлы по-прежнему не будут присутствовать на app2
, однако второй cookie-файл с другим именем теперь виден на app1
поддомене.
Похоже, что бы я ни делал, все cookie устанавливаются на app1
поддомен. Эти cookie-файлы также присутствуют при проверке example.com
.
Более того, когда app2.example.com
делает запрос к api
its, он отправляет обратно все cookie, видимые на app1
.
Правильно ли такое поведение? Связано ли это с тем, что CORS включен на стороне сервера? Как я могу разделить cookie между app1
и app2
?
редактировать: добавлен код конфигурации cors
Комментарии:
1. можете ли вы показать мне свою реализацию CORS? На мой взгляд, у вас проблема с CORS.
2. Я добавил конфигурацию nginx cors к вопросу.
3. Можете ли вы показать мне заголовки ответов из этого:
curl -X OPTIONS 'api.example.com' -H "Origin: app1.example.com" -H "Access-Control-Request-Method: GET" -Iv -o /dev/null
Похоже, что ваша реализация CORS в порядке.4. Вот результат. Ofc Я запросил надлежащий ресурс в качестве надлежащего источника, изменил его на
app1
при публикации: pastebin.com/raw/nUuJAmZE5. По моему мнению, что-то не так в вашем приложении, потому что ваша реализация CORS правильная (но небезопасная). Вы получили допустимые заголовки по вышеуказанному запросу.
Ответ №1:
Домен cookie в заголовке set-cookie должен соответствовать хосту, с которого он был запрошен. Необходимы как CORS, так и заголовки cookie. Если вы не устанавливаете домен в Set-Cookie, браузер примет полное доменное имя запрошенного хоста. Если вы все-таки установили домен, вы можете совместно использовать cookie-файлы между сайтами в одном домене, используя domain=example.com или аналогичный.
Возможно, хотя и сбивает с толку, установить одинаковое имя cookie на хосте с полным доменным именем и в домене, в котором находится хост. Один файл будет отправлен другим хостам в этом домене, и оба будут отправлены при последующих вызовах одного и того же полного доменного имени.
Я полагаю, вы хотите, чтобы cookie был в вашем домене, а не в полном доменном имени. Вы должны иметь возможность переписать заголовок Set-Cookie, возвращаемый apt, app1 и app2, чтобы они находились в домене вместо этого. Лучше исправить cookie-файлы в самих приложениях, если это возможно.
Комментарии:
1. Увы, если бы я мог прокомментировать вместо ответа, я бы это сделал. Но человек получает права на ответ до получения прав на комментарий.