Почему Chrome устанавливает cookie на неправильный поддомен?

#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/nUuJAmZE

5. По моему мнению, что-то не так в вашем приложении, потому что ваша реализация CORS правильная (но небезопасная). Вы получили допустимые заголовки по вышеуказанному запросу.

Ответ №1:

Домен cookie в заголовке set-cookie должен соответствовать хосту, с которого он был запрошен. Необходимы как CORS, так и заголовки cookie. Если вы не устанавливаете домен в Set-Cookie, браузер примет полное доменное имя запрошенного хоста. Если вы все-таки установили домен, вы можете совместно использовать cookie-файлы между сайтами в одном домене, используя domain=example.com или аналогичный.

Возможно, хотя и сбивает с толку, установить одинаковое имя cookie на хосте с полным доменным именем и в домене, в котором находится хост. Один файл будет отправлен другим хостам в этом домене, и оба будут отправлены при последующих вызовах одного и того же полного доменного имени.

Я полагаю, вы хотите, чтобы cookie был в вашем домене, а не в полном доменном имени. Вы должны иметь возможность переписать заголовок Set-Cookie, возвращаемый apt, app1 и app2, чтобы они находились в домене вместо этого. Лучше исправить cookie-файлы в самих приложениях, если это возможно.

Комментарии:

1. Увы, если бы я мог прокомментировать вместо ответа, я бы это сделал. Но человек получает права на ответ до получения прав на комментарий.