Search code examples
reactjsaxioscors

React: CORS error when API 302 redirects to same domain


I have a React web app (a.com) that communicates with an API (b.api) via axios/XHR requests.

Now there is a specific request that the server answers with a 302 redirect to another a.com location. This fails with a CORS error in Chrome:

Access to XMLHttpRequest at 'https://a.com/redirectpath' (redirected from 'https://b.api/requestpath') from origin 'https://a.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Contrary to the error message, the preflight request of the triggered redirect seems to have origin: null set. Is this the problem? Why does this happen, if the redirect goes to the same domain the user is on (a.com)?

Thank you for any ides!


Solution

  • From what I understood, this is what happened:

    • Browser makes a cross-origin request with Authorization header to b.api.
    • The Authorization header necessitates a preflight request, which is successful.
    • The response from b.api is a 302 redirect to a.com.
    • The browser makes the redirected request to a.com, which includes the same Authorization header again.
    • Although this request goes to the same origin, it is still considered cross-origin because it was triggered by a redirect from a different origin. (See also the difference between "HTTP-redirect fetch" and "scheme fetch" explained here.)
    • The Authorization header therefore necessitates a preflight request to a.com, with Origin: null.
    • This second preflight request is unsuccessful: a.com does not return Access-Control-Allow-Origin (nor Access-Control-Allow-Headers: Authorization).

    I think the problem is the behavior of b.api: A cross-origin-enabled request that requires an Authorization header should not lead to a 302 response, because that carries over the Authorization header (and with it the credential!) to a different server.

    More fundamentally, requests that contain credentials in an Authorization header are typically made by a server that is able to keep the credentials secret, not by a react app where the credentials are vulnerable to cross-site scripting attacks. For server-to-server requests, CORS is not involved at all. But b.api seems not to share this view, otherwise it would not need to cross-site-enable such requests.