Как указать браузеру включать файл cookie в запросы после обновления окна?

У меня есть серверная часть Spring-Boot и интерфейс React (написанный на Typescript и использующий HTTP-клиент Axios). Каждое из этих приложений размещается в другом поддомене общего родительского домена.

Я пытаюсь использовать аутентификацию на основе файлов cookie для серверной части и сталкиваюсь со следующей проблемой:

  1. Запрос на вход выполняется интерфейсом, а сервер возвращает ответ с заголовком Set-Cookie.
  2. При запросах к серверной части в рамках одного и того же сеанса окна браузера (т. е. та же вкладка, отсутствие обновлений страницы и т. д.) браузер включает файл cookie, который был установлен на шаге 1.
  3. Если страница обновляется (или если к приложению пытаются получить доступ с отдельной вкладки), браузер не включает файлы cookie в запросы, сделанные внешним интерфейсом.

Больше контекста:
(с примерами URL)

  • Серверная часть размещена по адресу https://api.example.com.
  • Внешний интерфейс размещен по адресу https://ui.example.com.
  • Заголовок Set-Cookie выглядит так: EXAMPLE_SESSION_ID=55A66FFAB27931F115D9E6BA23A11EE4; Max-Age=7200; Expires=Sun, 08-Nov-2020 23:53:39 GMT; Domain=example.com; Path=/; Secure; HttpOnly; SameSite=None
  • CORS Headers:
    • Access-Control-Allow-Origin: https://ui.example.com
    • Access-Control-Allow-Credentials: true

Может ли кто-нибудь помочь мне понять, почему файл cookie не включается в запросы к серверной части после обновления страницы?

Редактировать

Вот код для настройки CORS и файлов cookie.

Внутренняя конфигурация CORS

    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration corsConfiguration = new CorsConfiguration().applyPermitDefaultValues();
        corsConfiguration.setAllowedOrigins(getAllowedOrigins());
        corsConfiguration.setAllowCredentials(true);
        corsConfiguration.setAllowedHeaders(
                List.of(
                        "origin",
                        "content-type",
                        "accept",
                        "cookie",
                        "x-csrf-token"
                )
        );
        corsConfiguration.setAllowedMethods(
                List.of(
                        HttpMethod.OPTIONS.name(),
                        HttpMethod.GET.name(),
                        HttpMethod.POST.name(),
                        HttpMethod.PUT.name(),
                        HttpMethod.PATCH.name(),
                        HttpMethod.DELETE.name()
                )
        );

        UrlBasedCorsConfigurationSource corsConfigSource = new UrlBasedCorsConfigurationSource();
        corsConfigSource.registerCorsConfiguration("/**", corsConfiguration);
        return corsConfigSource;
    }

Настройка внутренних файлов cookie

    @Getter
    @Value("${my.custom.property.session.cookie.domain:}")
    private String customPropertyCookieDomain;

    @Bean
    public WebServerFactoryCustomizer<TomcatServletWebServerFactory> stackOverflowExampleWebServerCustomizer() {
        return factory -> {
            factory.addContextCustomizers(customizer -> {
                Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
                cookieProcessor.setSameSiteCookies("None");
                customizer.setCookieProcessor(cookieProcessor);

                if (StringUtils.isNotBlank(customPropertyCookieDomain)) {
                    customizer.setSessionCookieDomain(customPropertyCookieDomain);
                }
            });
        };
    }

person Gavin Killough    schedule 08.11.2020    source источник
comment
хорошо, вместо того, чтобы объяснять свой код, почему бы вам не включить какой-нибудь код?   -  person Toerktumlare    schedule 09.11.2020
comment
Я не уверен, что код будет ценным здесь. Я задаю вопрос о поведении браузера и мне интересно, какие свойства могут отсутствовать в моих файлах cookie/заголовках.   -  person Gavin Killough    schedule 09.11.2020


Ответы (1)


Потратив часы на вкладку «Сеть» в Google Chrome, я решил проверить, будет ли работать файл cookie, который я устанавливал, если я попытаюсь получить доступ к серверной части напрямую через браузер. Разумеется, файл cookie постоянно отправлялся даже при обновлении страницы и попытках открыть новые вкладки. Я немного покопался, и оказалось, что проблема на самом деле была связана с интерфейсом. HTTP-клиент Axios не устанавливал флаг withCredentials после обновления страницы. Поскольку в моей конфигурации CORS для параметра Access-Control-Allow-Credentials было задано значение true, предварительная проверка (OPTIONS) запрос-ответ не соответствовала файлу cookie, поэтому браузер перестал добавлять файл cookie к заголовкам запроса.

Этот ответ объясняет основную причину проблемы с Axios.

TLDR

Когда я обновил интерфейс в браузере, Axios больше не устанавливал withCredentials=true.

person Gavin Killough    schedule 10.11.2020