我的目标是将GET请求(包括cookie)从要托管在多个域中的javascript发出到公共域中的API。如果缺少cookie,我将创建一个cookie,然后将其返回以用于后续请求。
最初,我遇到了一个浏览器问题,该浏览器拒绝让jQuery进入与页面域不同的域,我知道这与CSRF保护有关。
我尝试了多种方法来设置DotNet Core 2.1 API项目的CORS,例如此问题How to enable CORS in ASP.NET Core中所述,以及类似这样的众多博客:https://weblog.west-wind.com/posts/2016/Sep/26/ASPNET-Core-and-CORS-Gotchas
尽管我能够解决CSRF问题,但是cookie从未在请求中传递,因此每次服务器创建一个新的cookie并将其发送回时,浏览器要么不保留它,要么不发送它以及随后对服务器的请求。
然后我发现,如果将SameSite = SameSiteMode.None
行添加到cookie创建中,它将起作用:
[HttpGet("[action]")]
public async Task<IActionResult> Track()
{
const string cookieName = "TrackingCookie";
string uniqueId = Request.Cookies[cookieName];
if (string.IsNullOrWhiteSpace(uniqueId))
{
uniqueId = "123"; // debug - this would be generated
Response.Cookies.Append(cookieName, uniqueId, new CookieOptions
{
SameSite = SameSiteMode.None,
Expires = DateTimeOffset.UtcNow.AddSeconds(30) // debug - short duration for testing only
});
logger.LogWarning($"Cookie missing, so created it with unique id '{uniqueId}'.");
return Created(Url.Action(), $"Created unique id '{uniqueId}'.");
}
logger.LogWarning($"Cookie found, unique id '{uniqueId}' present.");
}
但是,我还发现,如果从Startup.cs文件中删除所有与CORS相关的声明,它仍然可以使用。如果我将其完全删除,它仍然可以工作:
services.AddCors(options => options.AddPolicy("MyPolicy", builder =>
{
builder.WithOrigins("http://markscoolsite.com:5000")
.AllowAnyMethod()
.AllowAnyHeader();
}));
和:
app.UseCors("MyPolicy");
此外,无论我将Cookie放在哪个域上,该cookie都可以工作,因此显然它没有承认WithOrigins(...)
指令。
作为参考,这是我的javascript代码:
$(function () {
$.ajaxSetup({ xhrFields: { withCredentials: true } });
$.get('http://localhost:5000/api/tracking/track')
.done(console.log);
});
答案 0 :(得分:0)
好吧,我知道了。
CORS基本上与服务器将收到的内容无关,而是与浏览器将接受的内容无关。如果没有以下代码,由于抗CSRF保护,浏览器将拒绝来自服务器的响应:
app.UseCors(configurePolicy =>
{
configurePolicy.WithOrigins("http://markscoolsite.com:5000")
.AllowCredentials();
});
因此,如果我希望浏览器接收任何内容,则需要此代码。我只关注服务器对Cookie的接收。