Set-cookie 不适用于 Dot net Core 3.1 中的跨站点请求/响应和 React 设置同站点 cookie 和/或 CORS 问题

Posted

技术标签:

【中文标题】Set-cookie 不适用于 Dot net Core 3.1 中的跨站点请求/响应和 React 设置同站点 cookie 和/或 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 【发布时间】:2020-09-02 05:59:41 【问题描述】:

好吧,我被难住了!我一直在尝试解决这个问题几个小时,但没有运气。我正在关注this guide 在我正在学习整个设置的 Dot Net Core 3.1 / React.js (typescript) 项目中使用 JWT 进行身份验证。我正在使用跨站点请求。我的 React 服务器在 https://localhost:3000 上进行通信(使用 Visual Studio Code 进行开发),而我的 API / 后端 API 服务器在 https://localhost:44309 上运行,并在 Visual Studio 中运行。

我正在尝试将刷新令牌发送回客户端,并且指南指出这需要位于仅 HTTP cookie 中以缓解 XSS。无论我尝试什么,我都无法让浏览器在客户端执行“set-cookie”,因此我可以在 Google Chrome 的开发工具 > 应用程序 > Cookies 中看到它。这适用于我在响应中设置的任何 cookie。如果我使用 Google Chrome 的开发者工具面板,在网络响应中我可以看到“set-cookie”标题,但它们从未显示在“应用程序 > Cookies > LocalHost”中。我发送的响应发送有效负载,可以毫无问题地使用/读取。它只是不会设置 cookie!

当我为客户端和服务器应用程序部分使用相同的服务器时,设置工作正常(只需在标准 Visual Studio 设置中的 IIS 中运行它);任何/所有 cookie 设置都没有问题,所以我猜我正在处理跨站点问题。我只是不知道如何解决它。

我的代码:

//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 选项的组合,包括添加域/路径(以及相同站点属性的所有变体) 我在 CORS 政策中尝试了不同的方法(例如省略 .AllowCredentials) 我尝试过使用 http 而不是 https Firefox 仍然存在与 Google Chrome 不存在的请求有关的 CORS 问题 问题反映在 MS Edge 中 全部在 Windows 10 中运行 我对此比较陌生,所以如果我遗漏了什么,请告诉我。

非常感谢任何帮助。非常感谢,保罗

【问题讨论】:

【参考方案1】:

在为此投入了好几个小时后,这是客户端需要的一个简单修复。上面的设置是/很好并且工作正常,特别提到这一点:

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 调用,因此需要设置一个全局默认值以匹配此/与此标头一起工作。所以至少在程序中导入axios的地方,默认是这样设置的:

import axios from 'axios';
axios.defaults.withCredentials = true;

我有一个自定义 axios 创建者文件设置,以便我可以使用例如拦截器等,这是我放置这段代码的地方。一旦这两个东西被添加并对齐,cookies就被设置好了。

希望对你有帮助。

【讨论】:

我正在尝试在后端添加 cookie。它们被添加,但实际上没有被保存 - 所以在这个意义上,情况与描述的相似。 AllowCredentials() 存在。 我做了这一切,但还是没用。实际上它在浏览器中有非常详细的信息,用于 cookie ***.com/a/68241588/4367158

以上是关于Set-cookie 不适用于 Dot net Core 3.1 中的跨站点请求/响应和 React 设置同站点 cookie 和/或 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

res.cookie 不适用于 apollo-server-express

RegEx 不适用于 .NET,但适用于其他 RegEx 实现

Oracle 快速连接故障转移不适用于 ODP.NET。获取连接请求超时错误

.net 4.7.1 C# OCX 事件处理程序适用于 win10x 86/64,不适用于 win7/8 x86/64

JQuery 数据表不适用于 ASP.NET MVC 5

DotNetOpenAuth 不适用于 MVC 5 RC