Problem

You are developing a nodejs web application having some UI and backend APIs (express). You encounter the following issue:

response to preflight request doesn't pass access control check: no 'access-control-allow-origin' header is present on the requested resource. origin 'https://yourweb.com' is therefore not allowed access

Pre Solution discussion

On the first google result, you may find following suggestions:

  • add some headers like "Access-Control-Allow-Origin" and "Access-Control-Allow-Headers".
  • add "Access-Control-Request-Headers"
  • Use Cors (https://www.npmjs.com/package/cors)
  • Allow OPTIONS httpresponse
  • etc

Well, none of them works (at least in my case)!

Reason

My UI application was built in backbone js (https://marionettejs.com/), and was using nodejs express backend. I was using Microsoft OTKA authentication URL(SSO).

So, UI was calling an API to fetch user information, and since the user is not authenticated. Backend denied the request, and send a 302 redirect to OKTA url. Since UI was calling API via XHR. And, when it got the redirect URL, and XHR automatically tries to load that OKTA URL, and failed as expected.

Note: No additional header will solve this issue. And, this is not related to CSP.

Solution

The solution is to not to tell XHR request to load that redirect URL, and let the user fetch call fails with 401. And, configure your javascript to go to that redirectUrl by using window object.

See code below:

$(document).ajaxError((e, x) => {
    if (x.status === 401) {
        //In case we got an unauthorized then please do redirect and
        // load the login page
        storage.set('callback', window.location.hash);
        window.location = jQuery.parseJSON(x.responseText).redirectUrl;
    }
    //else handle something
});

To Read

You can read more about this issue in wiki :https://en.wikipedia.org/wiki/Cross-origin_resource_sharing#Preflight_example

Ahh, this problem ate my 2 days.