.NET7下Kestrel托管的ASP.NET Web API与React的CORS配置问题
我开发的项目后端基于ASP.NET Web API,前端使用create-react-app搭建,目前二者无法正常通信,持续出现CORS错误。生产环境中API和网站均部署在IIS,没有任何问题,但本地用Kestrel托管的开发环境完全无法运行。之前开发环境是正常的,为适配IIS做了一些修改后,本地Kestrel环境就出现了这个问题。
每次通过React端的Axios.request发起HTTP请求时,都会收到以下错误:Access to XMLHttpRequest at 'https://localhost:7046/api/<insert route here>' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
我尝试在Microsoft Edge中安装Chrome应用商店的CORS Unblock插件,错误变为:Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
我已确认接口本身正常,用Postman调用完全没问题,但在浏览器中请求就会失败。
相关代码
后端Program.cs代码
using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using System.Text; using NLog; using NLog.Web; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.EntityFrameworkCore; using System.Configuration; namespace MyNewAPI { public class Program { public static void Main(string[] args) { var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); logger.Debug("API starting..."); try { var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCors(options => { options.AddPolicy(name: "_myAllowSpecificOrigins", policy => { policy.WithOrigins("http://localhost:3000") .WithMethods("PUT", "DELETE", "GET"); }); }); // Add services to the container. builder.Services.AddSqlServer<Context1>(builder.Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(3600)); builder.Services.AddSqlServer<Context2>(builder.Configuration.GetConnectionString("AbelConnection"), o => o.CommandTimeout(3600)); builder.Services.AddMySql<MySqlContext>(builder.Configuration.GetConnectionString("MilogConnection"), ServerVersion.AutoDetect(builder.Configuration.GetConnectionString("MilogConnection"))); builder.Services.Configure<DatabaseSettings>(builder.Configuration.GetSection("MongoConnection")); builder.Services.AddSingleton<VMFarmService>(); builder.Services.AddControllers(); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters { ValidateIssuer = false, ValidateAudience = false, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = builder.Configuration["Jwt:Issuer"], ValidAudience = builder.Configuration["Jwt:Audience"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:SecretKey"])) }; }); builder.Logging.ClearProviders(); builder.Host.UseNLog(); var app = builder.Build(); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseRouting(); //app.UseHttpsRedirection(); app.UseCors(); app.UseAuthentication(); app.UseAuthorization(); app.MapControllers(); app.Run(); } catch (Exception exception) { // NLog: catch setup errors logger.Error(exception, "Stopped program because of exception:"); throw; } finally { // Ensure to flush and stop internal timers/threads before application-exit (Avoid segmentation fault on Linux) NLog.LogManager.Shutdown(); } } } }
前端Axios请求代码
import axios from 'axios'; const MyAPI = { async getToken() { const data = JSON.stringify({ clientKey: process.env.REACT_APP_API_KEY, clientSecret: process.env.REACT_APP_API_SECRET }); const config = { method: "post", maxBodyLength: Infinity, withCredentials: false, url: process.env.REACT_APP_API_BASE_URL + "/api/Authorize/token", headers: { "Content-Type": "application/json" }, data: data }; const response = await axios.request(config); return response.data.token; }, } export default MyAPI;
已尝试的修改
为了测试,我临时放宽了CORS配置(清楚这样不安全,只是想先让请求通过,之后再收紧规则):
var MyAllowSpecificOrigins = "_myAllowSpecificOrigins"; var builder = WebApplication.CreateBuilder(args); builder.Services.AddCors(options => { options.AddPolicy(name: MyAllowSpecificOrigins, policy => { policy.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader(); }); });
同时将MyAllowSpecificOrigins添加到了app.UseCors()中,但问题依然没有解决。
内容的提问来源于stack exchange,提问作者alexcheernz

