Search code examples
reactjsasp.net-core.net-coreaxioscors

Getting CORS error rather than expected 429 response when rate limit is reached


In my backend I implemented an IpRateLimit middleware with the AspNetCoreRateLimit package in my .net core entity framework backend. When an IP Address x makes y calls in a specific time, it gets blocked for a certain time and the backend should return an 429 error and this works fine when testing with postman. But when the I make an request with axios, that is supposed to get blocked because of the ip rate limiter, I receive an axios error:

"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"

After receiving this error, I have added the needed header, but it hasn't changed the result. Other axios requests to my backend (also post, put and delete) work fine, but when the ip rate limiter hits, I just get the cors error.

I implemented the limiter in my application as in the following tutorial: https://edi.wang/post/2019/6/16/ip-rate-limit-for-aspnet-core

React axios request:

 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("*********************************************")
        }
    }
}

When requestion and limiter hits I always get in the err.request.status === 0 path.


Solution

  • Most server systems/runtimes by default don’t add application-set headers to 4xx and 5xx responses but instead only add them to 2xx success responses and maybe to 3xx redirects.

    So you may need to do explicit config to force headers to get added to 4xx responses, in order for that 429 response end up with the Access-Control-Allow-Origin header.

    In Apache and nginx for example, that’s done by adding the always keyword to the header-setting directive. Maybe your server system has some similar thing.

    You get a CORS error because that 429 error has no Access-Control-Allow-Origin header.