我有一个 .net 核心 webapi 项目设置为接受这样的跨源请求
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseCors(opts => opts
.WithOrigins("https://fiddle.jshell.net")
.AllowCredentials()
.AllowAnyMethod()
.AllowAnyHeader());
app.UseHttpsRedirection();
app.UseMvc();
}
这有一个带有 GET 方法的值 Controller
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
return Ok("cookies: " + string.Join(", ", HttpContext.Request.Cookies.Select(x => x.Key)));
}
}
现在我正尝试像这样从浏览器发送一个获取请求
fetch('https://api.domain.com/api/values', {
headers:
{
'Content-Type': 'application/json'
},
credentials: 'include',
mode: 'cors'
})
.then(function(resp){
resp.text().then(function(data) {
console.log(data);
})
})
.catch(function(err){
console.log(err)
});
但这不会将 cookie 从页面发送到 api。我在这里错过了什么?我已经尝试了所有我能找到的解决方案,包括关闭第三方 cookie
更新
因此,对于为什么这不起作用或任何权威消息来源说您不能跨域发送 cookie(甚至是跨域 != 跨域),我仍然没有答案。
我们发现,即使来自 sub-a.domian.com
的 cookie 也不会发送到 sub-b.domain.com
。我们“解决”这个问题的方法是创建一个永久绑定(bind)到 domain.com
的 cookie,因为这些 cookie 被发送到 sub-a.domain.com
和 sub-b.domain.com
。
最佳答案
CORS 唯一做的就是让浏览器使用来自跨域请求的响应,它不会使 cookie 跨域(有关将 cookie 附加到请求的条件的更多详细信息,请参阅 specification,它根本没有提到 CORS)。
如果 cookie 可以随跨源请求一起发送,那将是一个主要的安全漏洞,因为它会允许外部域从您自己的域获取敏感信息,例如用户 session token 。邪恶的开发人员可以创建提供有用服务的 API,然后使用该 API 从网站检索大量 session token (可以通过 Referer
header 轻松找到原始网站)。
您在 localhost
和不同端口上观察到的行为是正常的,因为 cookie 没有考虑端口,这是“出于历史原因”(引用:Are HTTP cookies port specific?)
所以留给你的选择是:
- 将 cookie
domain
设置为父域 - 考虑到您的服务器可以使用 header 而不是 cookie,所以根本不要使用 cookie(例如,将 localStorage 与 javascript 和 HTTP header 一起使用)
- 考虑到您掌握基础设施,对 UI 和 API 使用单一域,并在服务器端进行一些 URL 重写(例如:以
/api/...
开头的传入请求是用本地API URL重写,其他用本地UI URL重写)
关于javascript - 浏览器不在启用 CORS 的情况下跨域发送 cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56731229/