刷新窗口后,如何指示浏览器在请求中包含Cookie?

问题描述

我有一个Spring-Boot后端和一个React前端(用Typescript编写并使用Axios HTTP客户端)。这些应用程序中的每一个都托管在公共父域的不同子域上。

我正在尝试对后端使用基于cookie的身份验证,并遇到以下问题:

  1. 前端发出登录请求,后端返回带有“ Set-Cookie”标头的响应。
  2. 在同一“浏览器窗口会话”(即同一标签,没有页面刷新等)中向后端发出的请求中,浏览器将包含在步骤1中设置的cookie。
  3. 如果刷新页面(或者尝试从单独的选项卡访问应用程序),则浏览器在前端发出的请求中不包含任何cookie。

更多上下文:
(带有示例网址)

  • 后端托管在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标头:
    • Access-Control-Allow-Origin: https://ui.example.com
    • Access-Control-Allow-Credentials: true

有人可以帮我弄清楚为什么刷新页面后后端请求中没有包含cookie吗?

编辑

这是配置CORS和Cookies的代码

后端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);
                }
            });
        };
    }

解决方法

在花了几个小时盯着Google Chrome浏览器的“网络”标签后,我决定看看如果尝试直接通过浏览器访问后端,我设置的cookie是否可以正常工作。果然,即使页面刷新并尝试在新选项卡中,cookie仍被一致发送。我做了一些挖掘,结果发现问题实际上与前端有关。刷新页面后,Axios HTTP客户端未设置withCredentials标志。因为我的CORS配置将Access-Control-Allow-Credentials设置为true,所以预检(OPTIONS)请求-响应与cookie不匹配,因此浏览器停止了将cookie追加到请求标头。

This answer解释了Axios问题的根本原因。

TLDR

当我在浏览器中刷新前端时,Axios不再设置withCredentials=true

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...