如何使用 ASP.NET Core 解决 REACT 中的 CORS 错误

ata*_*ati 11 cors asp.net-web-api reactjs asp.net-core axios

我有一个 ASP.NET Core Web API 和一个单独的 React 应用程序。Web API 使用 Windows 身份验证。当部署到服务器时,我没有任何问题,但是当我尝试在本地运行应用程序时,我会收到 CORS 错误,并且仅在 POST 操作上出现。这是我的Startup.cs

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Server.DAL;
using Server.Data;

namespace Server
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<AppDbContext>(options => options
               .UseSqlServer(Configuration.GetConnectionString("DatabaseConnection"))
               .UseLazyLoadingProxies());

            services.AddScoped<IUnitOfWork, UnitOfWork>();

            services.AddControllers();

            services.AddCors(options => options.AddPolicy("CorsPolicy",
                builder =>
                {
                    builder
                    .WithOrigins("http://localhost:3000")                        
                    .AllowAnyMethod()
                    .AllowAnyHeader()
                    .AllowCredentials();
                }));    
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseSwagger();

            app.UseHttpsRedirection();

            app.UseRouting();

            app.UseCors("CorsPolicy");

            app.UseAuthorization();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而且,这是我在 React 应用程序中的 axios 配置:

import axios, { AxiosInstance } from "axios";

let axiosInstance: AxiosInstance;

const axiosBaseConfig = {
  baseURL: process.env.REACT_APP_BASE_URL,
  timeout: 1000 * 20,
  withCredentials: true,
  headers: {
    Accept: "applicaiton/json",
    "Content-Type": "application/json",
  },
};

export const getAxios = () => {
  if (axiosInstance) {
    return axiosInstance;
  }

  axiosInstance = axios.create(axiosBaseConfig);

  return axiosInstance;
};
Run Code Online (Sandbox Code Playgroud)

我在这里遗漏或做错了什么吗?

更新:

这是我收到的 CORS 错误:

从源“http://localhost:3000”访问“https://localhost:44376/api/reservation”的 XMLHttpRequest 已被 CORS 策略阻止:对预检请求的响应未通过访问控制检查:值响应中的“Access-Control-Allow-Credentials”标头为“”,当请求的凭据模式为“include”时,该标头必须为“true”。XMLHttpRequest 发起的请求的凭据模式由 withCredentials 属性控制。

Pri*_*kar 12

尝试这个:-

在你的ConfigureServices

services.AddCors();
Run Code Online (Sandbox Code Playgroud)

和你的配置方法app.UseCors(x => x.AllowAnyHeader().AllowAnyMethod().WithOrigins("http://localhost:3000"));

希望它能解决您的问题。


小智 5

如果你有一个 create-react-app 项目,解决这个问题的方法是通过proxy后端的 url 添加一个属性到你的 package.json 文件中

{
...
   "proxy": "https://localhost:44376"
...
}
Run Code Online (Sandbox Code Playgroud)

现在 yow 获取的 url 必须是相对的

fetch("/api/users")
Run Code Online (Sandbox Code Playgroud)

代替

fetch("https://localhost:44376/api/users")
Run Code Online (Sandbox Code Playgroud)


ata*_*ati 2

韩斐和乔纳森·阿尔法罗为我指明了正确的方向,我终于找到了解决方案。正如 Fei Han 在他的回答中正确指出的那样,CORS 预检请求始终是匿名的,并且它们使用 HTTP OPTIONS 方法。所以,这就是我为解决该问题所做的事情。

  1. 启用匿名身份验证launchSettings.json
  "iisSettings": {
    "windowsAuthentication": true,
    "anonymousAuthentication": true,
    "iisExpress": {
      "applicationUrl": "http://localhost:62682",
      "sslPort": 44376
    }
  },
Run Code Online (Sandbox Code Playgroud)
  1. 创建一个如下所示的身份验证中间件,如果 http 请求具有除OPTIONS用户未经过身份验证之外的任何方法,则返回 401。
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using System.Threading.Tasks;

namespace Server
{
    public class AuthenticationMiddleware
    {
        private readonly RequestDelegate _next;

        public AuthenticationMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            BeginInvoke(context);
            await _next.Invoke(context);
        }

        private async void BeginInvoke(HttpContext context)
        {
            if (context.Request.Method != "OPTIONS" && !context.User.Identity.IsAuthenticated)
            {
                context.Response.StatusCode = 401;
                await context.Response.WriteAsync("Not Authenticated");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)
  1. 使用中间件Startup.cs
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
 
    app.UseSwagger();

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseMiddleware<AuthenticationMiddleware>();

    app.UseCors("CorsPolicy");

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

23979 次

最近记录:

2 年,5 月 前