You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React应用调用ABP.IO Swagger接口出现CORS错误(OpenIddict)

解决ABP.IO后端对接React前端的CORS跨域问题

1. 配置后端appsettings.json的CORS规则

在后端HttpApiHost项目的appsettings.json中添加CORS配置,将AllowedOrigins替换为你的React应用实际运行地址(比如http://localhost:3000):

"App": {
  "CorsOrigins": "http://localhost:3000"
}

2. 在模块类中启用CORS服务与中间件

打开后端模块类(如YourProjectNameHttpApiHostModule),在ConfigureServices方法中添加CORS服务配置:

public override void ConfigureServices(ServiceConfigurationContext context)
{
    var configuration = context.Services.GetConfiguration();

    // 其他配置...

    // 配置CORS策略
    context.Services.AddCors(options =>
    {
        options.AddPolicy("AllowReactOrigin",
            policy =>
            {
                policy.WithOrigins(configuration["App:CorsOrigins"].Split(",", StringSplitOptions.RemoveEmptyEntries))
                    .AllowAnyHeader()
                    .AllowAnyMethod()
                    .AllowCredentials();
            });
    });
}

接着在Configure方法中添加CORS中间件,注意中间件顺序必须放在UseRouting之后,UseAuthentication、UseAuthorization之前:

public override void Configure(ApplicationConfigurationContext context)
{
    var app = context.GetApplicationBuilder();

    // 其他中间件配置...

    app.UseRouting();

    // 启用CORS策略
    app.UseCors("AllowReactOrigin");

    app.UseAuthentication();
    app.UseAuthorization();

    // 其他中间件...
}

3. 配置OpenIddict客户端的跨域允许

你已经配置了OpenIddict数据种子,需要补充客户端的AllowedCorsOrigins配置。在OpenIdDictDataSeedContributor的SeedAsync方法中,找到客户端创建的代码,添加允许的React地址:

var clientId = "YourProjectName_App";
await CreateClientAsync(
    name: clientId,
    scopes: commonScopes.Union(new[] { "YourProjectName" }),
    grantTypes: new[] { "authorization_code", "refresh_token" },
    secret: "1q2w3e*",
    redirectUris: new[] { "http://localhost:3000/authentication/login-callback" },
    postLogoutRedirectUris: new[] { "http://localhost:3000/authentication/logout-callback" },
    allowedCorsOrigins: new[] { "http://localhost:3000" }
);

如果你的CreateClientAsync方法没有allowedCorsOrigins参数,需要修改方法逻辑,在创建OpenIddictApplicationDescriptor时添加:

private async Task CreateClientAsync(
    string name,
    IEnumerable<string> scopes,
    IEnumerable<string> grantTypes,
    string secret = null,
    IEnumerable<string> redirectUris = null,
    IEnumerable<string> postLogoutRedirectUris = null,
    IEnumerable<string> allowedCorsOrigins = null)
{
    var application = await _openIddictApplicationManager.FindByClientIdAsync(name);
    if (application != null) return;

    var descriptor = new OpenIddictApplicationDescriptor
    {
        ClientId = name,
        DisplayName = name,
        RedirectUris = redirectUris?.Select(uri => new Uri(uri)).ToList(),
        PostLogoutRedirectUris = postLogoutRedirectUris?.Select(uri => new Uri(uri)).ToList(),
        Permissions =
        {
            OpenIddictConstants.Permissions.Endpoints.Authorization,
            OpenIddictConstants.Permissions.Endpoints.Logout,
            OpenIddictConstants.Permissions.Endpoints.Token,
            OpenIddictConstants.Permissions.GrantTypes.AuthorizationCode,
            OpenIddictConstants.Permissions.GrantTypes.RefreshToken
        },
        Requirements =
        {
            OpenIddictConstants.Requirements.Features.ProofKeyForCodeExchange
        }
    };

    // 添加允许的跨域Origin
    if (allowedCorsOrigins != null)
    {
        foreach (var origin in allowedCorsOrigins)
        {
            descriptor.AllowedCorsOrigins.Add(new Uri(origin));
        }
    }

    // 配置客户端密钥(如果需要)
    if (!string.IsNullOrEmpty(secret))
    {
        descriptor.ClientSecret = secret;
    }

    await _openIddictApplicationManager.CreateAsync(descriptor);
}

4. 验证与注意事项

  • 确保配置中的React地址和实际运行地址完全一致(包括HTTP/HTTPS、端口号,不能有末尾斜杠的差异)
  • 修改配置后务必重启后端服务,确保配置生效
  • 你的React用HTTP、后端用HTTPS属于混合内容场景,浏览器可能触发额外限制,建议React也改用HTTPS启动(执行HTTPS=true npm start),避免后续其他问题

内容的提问来源于stack exchange,提问作者Sebbas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 00:37:37