刷新窗口后,如何指示浏览器在请求中包含 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中读取它,以便我可以在请求头中包含它?