达到速率限制时收到 CORS 错误而不是预期的 429 响应

Posted

技术标签:

【中文标题】达到速率限制时收到 CORS 错误而不是预期的 429 响应【英文标题】:Getting CORS error rather than expected 429 response when rate limit is reached 【发布时间】:2021-07-23 00:35:18 【问题描述】:

在我的后端中,我在 .net 核心实体框架后端中使用 AspNetCoreRateLimit 包实现了 IpRateLimit 中间件。当 IP 地址 x 在特定时间进行 y 调用时,它会被阻塞一段时间,并且后端应该返回 429 错误,这在使用邮递员进行测试时可以正常工作。但是当我使用 axios 发出请求时,由于 ip 速率限制器应该被阻止,我收到 axios 错误:

"Access to XMLHttpRequest at 'https://localhost:44372/api/Users/Login/' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource."
"POST https://localhost:44372/api/Users/Login/ net::ERR_FAILED"

收到此错误后,我添加了所需的标头,但并没有改变结果。对我的后端的其他 axios 请求(也包括发布、放置和删除)工作正常,但是当 ip 速率限制器命中时,我只会收到 cors 错误。

我在我的应用程序中实现了限制器,如下面的教程: https://edi.wang/post/2019/6/16/ip-rate-limit-for-aspnet-core

响应 axios 请求:

 async function buildPostAndFetch(url, param, header) 
            const finalurl = `$BASE_URL$url`;
            return axios.post(finalurl, param, headers:"Access-Control-Allow-Origin": "*")
            .then(res => 
                response(res);
                return res.data ? res.data : true;
            )
            .catch(err =>               
                handleError(err);
                return false;
            )        
    

handleError() 
 const handleError = err => 
        setError(true);
   
        if(err.request?.status === 0) 
            console.log("*********************************************")
            console.log(err.request);
            console.log("*********************************************")
            // throw new Error("API is currently offline or you are not connected to the internet:(");
         else if(err.response.status === 429) 
            console.log("*********************************************")
            console.log(err.response);
            console.log("*********************************************")
        
    

当请求和限制器命中时,我总是进入 err.request.status === 0 路径。

【问题讨论】:

你应该使用 nginx 将你的请求代理到同一个 ip:port 以避免 CROS 限制,比如 axios -> nginx -> server @Niklas 你能详细解释一下吗?我不想避免限制,但我不明白,为什么我收到 CORS 错误,而不是配置的 429 错误代码 您为什么收到 CROS?因为发送请求端口是从3000到44372,你应该发送3000到3000,怎么解决?我是我的项目,我转发 nginx @Niklas 的请求 限制率收到 CROS 错误是有线的,如果您通过添加标头修复 CROS,它应该返回 429。 @尼克拉斯 我应该添加哪个标题。所有其他请求都可以在不让前端和后端在同一端口上运行的情况下工作。我在后端配置了 CORS,如下所示: 【参考方案1】:

默认情况下,大多数服务器系统/运行时不会将应用程序集标头添加到 4xx5xx 响应中,而是仅将它们添加到 2xx 成功响应中,并且可能添加到 3xx 重定向中。

因此,您可能需要进行显式配置以强制将标头添加到 4xx 响应中,以便 429 响应最终带有 Access-Control-Allow-Origin 标头。

例如,在 Apache 和 nginx 中,这是通过将 always 关键字添加到 header-setting 指令来完成的。也许你的服务器系统也有类似的东西。

您收到 CORS 错误,因为 429 错误没有 Access-Control-Allow-Origin 标头。

【讨论】:

【参考方案2】:

首先,确保你有来自 NuGet 的Install-Package Microsoft.AspNetCore.Cors

然后,请将以下内容添加到您的Startup.cs

public void ConfigureServices(IServiceCollection services)

    // Put it before AddMvc() if there's any
    services.AddCors();

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

    // Put it before UseMvc() if there's any
    app.UseCors(
        options => options
            .WithOrigins("http://localhost:3000")
            .AllowAnyHeader()
            .AllowAnyMethod()
    );

    app.UseMvc();

完成上述配置后,通过检查您的网络选项卡(浏览器的开发人员工具),您可能会看到返回的响应标头之一是access-control-allow-origin : http://localhost:3000

【讨论】:

我已经尝试过了,但没有任何改变。我认为错误必须来自我的前端,因为发出这个请求并得到 429 错误,如果它应该在使用邮递员时工作正常【参考方案3】:

试试:

app.UseCors(opt => opt
    .WithOrigins("http://localhost:3000"")
    .AllowAnyHeader()
    .AllowAnyMethod());

协议(http/https)不能省略。另外,cors 中间件应该放在app.UseRouting 之后,UseAuthorization 之前。

你可以看到Middleware Order。

【讨论】:

请补充说明

以上是关于达到速率限制时收到 CORS 错误而不是预期的 429 响应的主要内容,如果未能解决你的问题,请参考以下文章

当我收到本地文件的 CORS 错误时该怎么办? [复制]

在本地调用 Firebase 云函数时,我收到 200 响应,但响应是 cors 类型响应,而不是我的实际数据

Twitter API - POST收藏夹/创建特定速率限制

当我根据 DynDNS url 名称而不是 IP 发出 axios 请求时,为啥会出现 CORS 错误?

如何使用 Python 绕过速率限制 ..HTML 错误 1015

为啥在使用 Angular http.post 而不是传统的 HTML 表单时会出现 CORS 错误?