Set-cookie 不适用于 Dot net Core 3.1 和 React 设置中的 cross-site 请求/响应 same-site cookies and/or CORS 问题
Set-cookie not working for cross-site request / response in Dot net Core 3.1 & React setup same-site cookies and/or CORS issue
好吧,我难住了!几个小时以来,我一直在尝试解决这个问题,但没有运气。我在 Visual Studio.
关注 this guide to use JWT for auth in a Dot Net Core 3.1 / React.js (typescript) project I am working on to learn the whole setup. I am working using cross site requests. My React server is communicating on https://localhost:3000 (dev using Visual Studio Code), and my API / back end, API server is running on https://localhost:44309 运行ning
我正在尝试将刷新令牌发送回客户端,指南指出这需要位于 HTTP Only cookie 中以缓解 XSS。无论我尝试什么,我都无法让浏览器在客户端执行“set-cookie”,所以我可以在 Google Chrome 的 Dev Tools > Application > Cookies 中看到它。这适用于我在响应中设置的任何 cookie。如果我使用 Google Chrome 的开发人员工具面板,在网络响应中我可以看到 'set-cookie' headers 在那里,但它们永远不会显示在 'Application > Cookies > LocalHost'。我发送的响应发送有效载荷,可以毫无问题地使用/读取。它只是不会设置 cookie!
当我为客户端和服务器应用程序部分使用相同的服务器时,设置工作正常(在标准 Visual Studio 设置的 IIS 中只是 运行 它);任何/所有 cookie 设置都没有问题,所以我猜我正在处理 cross-site 问题。我只是不知道如何解决它。
我的代码:
//setting up cors
services.AddCors(options =>
{
options.AddPolicy("CORSAllowLocalHost3000",
builder =>
builder.WithOrigins("https://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
});
//using cors
app.UseCors("CORSAllowLocalHost3000");
//setting up auth
services
.AddDefaultIdentity<ApplicationUser>
(
options =>
{
options.SignIn.RequireConfirmedAccount = false;
options.Password.RequiredLength = 6;
}
)
.AddEntityFrameworkStores<IdentityApplicationContext>();
services
.AddAuthentication(opts =>
{
opts.DefaultAuthenticateScheme = "JwtBearer";
opts.DefaultScheme = "JwtBearer";
opts.DefaultChallengeScheme = "JwtBearer";
})
.AddJwtBearer("JwtBearer", opts =>
{
opts.SaveToken = true;
opts.TokenValidationParameters = tokenValParams;
});
//tokenValParams to validate the JWT
var tokenValParams = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key:
Encoding.ASCII.GetBytes(configuration.GetSection("Authentication").GetSection("JwtBearer").GetSection("SecurityKey").Value)),
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
//for API only dev env, start as API only service - no browser - client app runs
app.UseStaticFiles();
if (!env.IsEnvironment("APIOnlyDevelopment"))
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
//spa.UseProxyToSpaDevelopmentServer("https://localhost:3000");
});
//Test Cookie generated in client before async Ok() result is returned in controller
HttpContext.Response.Cookies.Append("JwtRefreshTokenn", resultOfSignin.RefreshToken, new CookieOptions() { Secure = true, HttpOnly = true, SameSite = SameSiteMode.None});
Response.Cookies.Append("JwtRefreshTokenn2", resultOfSignin.RefreshToken, new CookieOptions() { HttpOnly = true, Secure = true, SameSite = SameSiteMode.None});
Response.Cookies.Append("JwtRefreshTokenn3", resultOfSignin.RefreshToken, new CookieOptions() { });
更多信息:
- 我已将 Visual Studio 中的“应用程序 URL”更改为“启用 SSL”URL 的应用程序,因为我在发生重定向时遇到 CORS 问题。
- 我运行使用内置的“HTTPS”设置连接服务器,并使用 npm 的 https 设置连接客户端应用程序
(包括像 this post 一样对证书错误进行排序)。
- 我已经尝试了 cookie 选项的所有组合,包括添加域/路径(以及 same-site 属性的所有变体)
- 我在 CORS 策略中尝试了不同的东西(例如省略 .AllowCredentials)
- 我试过使用 http 而不是 https
- 对于 Google Chrome 不是
的请求,Firefox 仍然存在 CORS 问题
- 问题反映在 MS Edge 中
- 所有运行宁在Windows 10
- 我对此比较陌生,所以如果我遗漏了什么,请告诉我。
非常感谢任何帮助。非常感谢,保罗
在为此投入了好几个小时之后,这是一个客户需要的简单修复。上面的设置是/很好并且工作正常,特别提到这一点:
services.AddCors(options =>
{
options.AddPolicy("CORSAllowLocalHost3000",
builder =>
builder.WithOrigins("https://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials() // <<< this is required for cookies to be set on the client - sets the 'Access-Control-Allow-Credentials' to true
);
});
由于客户端使用 axios 从 React 中进行 API 调用,因此需要设置一个全局默认值来匹配这个/与这个 header 一起工作。所以至少在程序中导入axios的地方,默认是这样设置的:
import axios from 'axios';
axios.defaults.withCredentials = true;
我有一个自定义的 axios creator 文件设置,这样我就可以使用例如拦截器等,这是我放置这段代码的地方。添加并对齐这两件事后,将设置 cookie。
希望对您有所帮助。
好吧,我难住了!几个小时以来,我一直在尝试解决这个问题,但没有运气。我在 Visual Studio.
关注 this guide to use JWT for auth in a Dot Net Core 3.1 / React.js (typescript) project I am working on to learn the whole setup. I am working using cross site requests. My React server is communicating on https://localhost:3000 (dev using Visual Studio Code), and my API / back end, API server is running on https://localhost:44309 运行ning我正在尝试将刷新令牌发送回客户端,指南指出这需要位于 HTTP Only cookie 中以缓解 XSS。无论我尝试什么,我都无法让浏览器在客户端执行“set-cookie”,所以我可以在 Google Chrome 的 Dev Tools > Application > Cookies 中看到它。这适用于我在响应中设置的任何 cookie。如果我使用 Google Chrome 的开发人员工具面板,在网络响应中我可以看到 'set-cookie' headers 在那里,但它们永远不会显示在 'Application > Cookies > LocalHost'。我发送的响应发送有效载荷,可以毫无问题地使用/读取。它只是不会设置 cookie!
当我为客户端和服务器应用程序部分使用相同的服务器时,设置工作正常(在标准 Visual Studio 设置的 IIS 中只是 运行 它);任何/所有 cookie 设置都没有问题,所以我猜我正在处理 cross-site 问题。我只是不知道如何解决它。
我的代码:
//setting up cors
services.AddCors(options =>
{
options.AddPolicy("CORSAllowLocalHost3000",
builder =>
builder.WithOrigins("https://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials()
);
});
//using cors
app.UseCors("CORSAllowLocalHost3000");
//setting up auth
services
.AddDefaultIdentity<ApplicationUser>
(
options =>
{
options.SignIn.RequireConfirmedAccount = false;
options.Password.RequiredLength = 6;
}
)
.AddEntityFrameworkStores<IdentityApplicationContext>();
services
.AddAuthentication(opts =>
{
opts.DefaultAuthenticateScheme = "JwtBearer";
opts.DefaultScheme = "JwtBearer";
opts.DefaultChallengeScheme = "JwtBearer";
})
.AddJwtBearer("JwtBearer", opts =>
{
opts.SaveToken = true;
opts.TokenValidationParameters = tokenValParams;
});
//tokenValParams to validate the JWT
var tokenValParams = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key:
Encoding.ASCII.GetBytes(configuration.GetSection("Authentication").GetSection("JwtBearer").GetSection("SecurityKey").Value)),
ValidateIssuer = false,
ValidateAudience = false,
RequireExpirationTime = false,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
//for API only dev env, start as API only service - no browser - client app runs
app.UseStaticFiles();
if (!env.IsEnvironment("APIOnlyDevelopment"))
app.UseSpaStaticFiles();
app.UseSpa(spa =>
{
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseReactDevelopmentServer(npmScript: "start");
//spa.UseProxyToSpaDevelopmentServer("https://localhost:3000");
});
//Test Cookie generated in client before async Ok() result is returned in controller
HttpContext.Response.Cookies.Append("JwtRefreshTokenn", resultOfSignin.RefreshToken, new CookieOptions() { Secure = true, HttpOnly = true, SameSite = SameSiteMode.None});
Response.Cookies.Append("JwtRefreshTokenn2", resultOfSignin.RefreshToken, new CookieOptions() { HttpOnly = true, Secure = true, SameSite = SameSiteMode.None});
Response.Cookies.Append("JwtRefreshTokenn3", resultOfSignin.RefreshToken, new CookieOptions() { });
更多信息:
- 我已将 Visual Studio 中的“应用程序 URL”更改为“启用 SSL”URL 的应用程序,因为我在发生重定向时遇到 CORS 问题。
- 我运行使用内置的“HTTPS”设置连接服务器,并使用 npm 的 https 设置连接客户端应用程序
(包括像 this post 一样对证书错误进行排序)。 - 我已经尝试了 cookie 选项的所有组合,包括添加域/路径(以及 same-site 属性的所有变体)
- 我在 CORS 策略中尝试了不同的东西(例如省略 .AllowCredentials)
- 我试过使用 http 而不是 https
- 对于 Google Chrome 不是 的请求,Firefox 仍然存在 CORS 问题
- 问题反映在 MS Edge 中
- 所有运行宁在Windows 10
- 我对此比较陌生,所以如果我遗漏了什么,请告诉我。
非常感谢任何帮助。非常感谢,保罗
在为此投入了好几个小时之后,这是一个客户需要的简单修复。上面的设置是/很好并且工作正常,特别提到这一点:
services.AddCors(options =>
{
options.AddPolicy("CORSAllowLocalHost3000",
builder =>
builder.WithOrigins("https://localhost:3000")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials() // <<< this is required for cookies to be set on the client - sets the 'Access-Control-Allow-Credentials' to true
);
});
由于客户端使用 axios 从 React 中进行 API 调用,因此需要设置一个全局默认值来匹配这个/与这个 header 一起工作。所以至少在程序中导入axios的地方,默认是这样设置的:
import axios from 'axios';
axios.defaults.withCredentials = true;
我有一个自定义的 axios creator 文件设置,这样我就可以使用例如拦截器等,这是我放置这段代码的地方。添加并对齐这两件事后,将设置 cookie。
希望对您有所帮助。