Javascript 不会设置在 XHR 响应中收到的 httpcookie
Javascript won't set httpcookie received in XHR response
我有一个基本的 SPA (react) <-> API (net core 2.2) 设置,有 2 个环境:dev 和 prod(小项目)。 API
端有一个身份验证机制,用于检查每个包含 JWT 的请求中是否存在 httponly
cookie。
在开发环境中,它可以工作 okey-dokey:allowCredentials()
设置在 API 中,withCredentials = true
也设置在 React 应用程序中。 运行 都在我本地主机的不同端口上。
但是在生产环境中(单独的 Heroku dynos),它不会设置 httponly
cookie:我可以使用我的凭据登录,response-headers 包含带有 jwt 的 cookie,但是我将发出的所有其他请求都不会在 request-headers 中包含 cookie header !
然后我收到 401 Unauthorized ...
错误(这是合乎逻辑的)。当我花了几个小时尝试所有事情时,它让我抓狂。
我的简单身份验证 XHR (vanilla) 调用:
var request = new XMLHttpRequest()
request.open('POST', apiAuthenticateUser, true)
request.setRequestHeader('Content-type', 'application/json')
request.withCredentials = true
request.send(postData)
我的 Startup.cs
.net 核心中的配置 api :
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
IdentityModelEventSource.ShowPII = true;
} else {
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors(
options => options.WithOrigins(
"https://localhost:3000",
"*productionEnvUrl*").AllowAnyMethod().AllowCredentials().AllowAnyHeader()
);
app.UseMvc(routes => {
routes.MapRoute("MainRoute", "api/{controller}/{action}");
});
app.UseAuthentication();
}
这就是我在 api 控制器操作响应中设置包含 jwt 的 httponly cookie 的方式:
Response.Cookies.Append("jwt", jwt, new CookieOptions { HttpOnly = true, Secure = true });
两种环境中的代码相同,只是产生不同的结果。在这两种情况下,api 在身份验证 response-headers 中向我发送正确的 cookie,但在生产环境中,我的 React 应用程序不会保留它并在其他 api 调用中将其发回...... .
这是从 API 收到的 cookie,它永远不会从网络应用发回:
Access-Control-Allow-Credentials :true
Access-Control-Allow-Origin :https://xxxxxxxxxx.com
Connection :keep-alive
Content-Type :application/json; charset=utf-8
Date :Mon, 09 Sep 2019 22:32:54 GMT
Server :Kestrel
Set-Cookie :jwt=xxxxxxxx; path=/; secure; samesite=lax; httponly
Transfer-Encoding :chunked
Vary :Origin
Via :1.1 vegur
如果有人有任何线索,我将永远感激不已。
原来我错了很多东西:
- 我的网络应用程序代码一切正常。
- 它在开发环境中工作,因为一切都在本地主机上 运行(只是不同的端口),这是由 samesite=lax(默认值)cookie 策略授权的。
- 为了使其跨域,您只需指定 samesite=none,然后它就可以工作了。它会产生一些潜在的漏洞,因为您失去了对 cookie 的一些控制,但除非您设置一些 reverse-proxy/api 网关机制,否则这是解决 cookie(包括 httponly)的唯一方法。
- 我对规则 "jwt should only be stored in httponly cookies" 感到过度兴奋:它也有漏洞,您仍然必须确保应用程序 xss(和其他技术)的其余部分安全。如果采取所有必要的预防措施,您可以安全地将 jwt 存储在本地存储中。
感谢@Crayon Violent 的宝贵时间:)
我有一个基本的 SPA (react) <-> API (net core 2.2) 设置,有 2 个环境:dev 和 prod(小项目)。 API
端有一个身份验证机制,用于检查每个包含 JWT 的请求中是否存在 httponly
cookie。
在开发环境中,它可以工作 okey-dokey:allowCredentials()
设置在 API 中,withCredentials = true
也设置在 React 应用程序中。 运行 都在我本地主机的不同端口上。
但是在生产环境中(单独的 Heroku dynos),它不会设置 httponly
cookie:我可以使用我的凭据登录,response-headers 包含带有 jwt 的 cookie,但是我将发出的所有其他请求都不会在 request-headers 中包含 cookie header !
然后我收到 401 Unauthorized ...
错误(这是合乎逻辑的)。当我花了几个小时尝试所有事情时,它让我抓狂。
我的简单身份验证 XHR (vanilla) 调用:
var request = new XMLHttpRequest()
request.open('POST', apiAuthenticateUser, true)
request.setRequestHeader('Content-type', 'application/json')
request.withCredentials = true
request.send(postData)
我的 Startup.cs
.net 核心中的配置 api :
public void Configure(IApplicationBuilder app, IHostingEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
IdentityModelEventSource.ShowPII = true;
} else {
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseCors(
options => options.WithOrigins(
"https://localhost:3000",
"*productionEnvUrl*").AllowAnyMethod().AllowCredentials().AllowAnyHeader()
);
app.UseMvc(routes => {
routes.MapRoute("MainRoute", "api/{controller}/{action}");
});
app.UseAuthentication();
}
这就是我在 api 控制器操作响应中设置包含 jwt 的 httponly cookie 的方式:
Response.Cookies.Append("jwt", jwt, new CookieOptions { HttpOnly = true, Secure = true });
两种环境中的代码相同,只是产生不同的结果。在这两种情况下,api 在身份验证 response-headers 中向我发送正确的 cookie,但在生产环境中,我的 React 应用程序不会保留它并在其他 api 调用中将其发回...... .
这是从 API 收到的 cookie,它永远不会从网络应用发回:
Access-Control-Allow-Credentials :true
Access-Control-Allow-Origin :https://xxxxxxxxxx.com
Connection :keep-alive
Content-Type :application/json; charset=utf-8
Date :Mon, 09 Sep 2019 22:32:54 GMT
Server :Kestrel
Set-Cookie :jwt=xxxxxxxx; path=/; secure; samesite=lax; httponly
Transfer-Encoding :chunked
Vary :Origin
Via :1.1 vegur
如果有人有任何线索,我将永远感激不已。
原来我错了很多东西:
- 我的网络应用程序代码一切正常。
- 它在开发环境中工作,因为一切都在本地主机上 运行(只是不同的端口),这是由 samesite=lax(默认值)cookie 策略授权的。
- 为了使其跨域,您只需指定 samesite=none,然后它就可以工作了。它会产生一些潜在的漏洞,因为您失去了对 cookie 的一些控制,但除非您设置一些 reverse-proxy/api 网关机制,否则这是解决 cookie(包括 httponly)的唯一方法。
- 我对规则 "jwt should only be stored in httponly cookies" 感到过度兴奋:它也有漏洞,您仍然必须确保应用程序 xss(和其他技术)的其余部分安全。如果采取所有必要的预防措施,您可以安全地将 jwt 存储在本地存储中。
感谢@Crayon Violent 的宝贵时间:)