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

Posted

技术标签:

【中文标题】刷新窗口后,如何指示浏览器在请求中包含 cookie?【英文标题】:How do I instruct a browser to include a cookie in requests after the window has been refreshed? 【发布时间】:2021-02-20 21:29:14 【问题描述】:

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

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

    前端发出登录请求,后端返回带有“Set-Cookie”标头的响应。 在同一“浏览器窗口会话”中向后端发出的请求(即相同的选项卡、无页面刷新等)时,浏览器会包含在步骤 1 中设置的 cookie。 如果页面被刷新(或者如果尝试从单独的选项卡访问应用程序),浏览器不会在前端发出的请求中包含任何 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 标头: 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> ***ExampleWebServerCustomizer() 
        return factory -> 
            factory.addContextCustomizers(customizer -> 
                Rfc6265CookieProcessor cookieProcessor = new Rfc6265CookieProcessor();
                cookieProcessor.setSameSiteCookies("None");
                customizer.setCookieProcessor(cookieProcessor);

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

【问题讨论】:

好吧,不解释你的代码,你为什么不包含一些代码呢? 我不确定代码在这里是否有价值。我在问一个有关浏览器行为的问题,并对我的 cookie/标头可能缺少哪些属性感到好奇。 【参考方案1】:

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

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

TLDR

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

【讨论】:

以上是关于刷新窗口后,如何指示浏览器在请求中包含 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rails 的 JSON 响应中包含 cookie?

如果用于认证的JWT令牌保存在HTTP-Only cookie中,你如何从cookie中读取它,以便我可以在请求头中包含它?

如何获取request请求携带的cookie

浏览器刷新页面后向服务器发出两次请求的问题

我的 HTML 中包含的 JavaScript 库可以使用我的 cookie 会话向我的网站发出请求吗?

如何在一个窗口中包含多个图表[重复]