node.jsexpressoauth-2.0corspreflight

CORS in OAuth: Response to preflight request doesn't pass access control check


So I'm trying to implement the OAuth 2 flow, while my webapp is the server that give away authorization code/access token.

Cors error happens when sending the code back to third-party website(zapier in this case):

XMLHttpRequest cannot load https://zapier.com/dashboard/auth/oauth/return/App505CLIAPI/?code=somecode&state=somestate. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://myurl' is therefore not allowed access.

If I manually open a new tab, paste that zapier uri, everything works perfectly.

Seems like a typical CORS issue, but none the popular solutions works for me:

  1. Add Access-Control-Allow-Origin: I'm using this oauth2orize library, and sending reponse to preflight seems also part of the library. So I cannot add header.
  2. Using cors: Have tried app.use(cors()) and app.options('*', cors()) which should apply to all routes, but simply not working.

My webapp sits on a node express server, in front of which there's an nginx proxy server.

Any idea where the problem might be is appreciated.


Solution

  • The issue that error message indicates isn’t caused by the app code running at https://myurl/. Instead it’s just that https://zapier.com/dashboard/auth/… doesn’t seem to support CORS.

    Specifically, the response from that https://zapier.com/dashboard/auth/… URL doesn’t include the Access-Control-Allow-Origin response header, so your browser won’t let your frontend JavaScript code access the response.

    It seems like that is all intentional on the part of Zapier—they don’t intend for that auth endpoint to be accessed from frontend AJAX/XHR/Fetch code running in a browser. Instead I guess it’s intended that you only access that auth endpoint from your backend code. Or something.

    Anyway there is no way from your side that you can fix the fact the response from that Zapier API endpoint doesn’t include Access-Control-Allow-Origin.

    And as long as it doesn’t include Access-Control-Allow-Origin, your browser blocks your frontend code from being able to get to the response—and there’s no way to get your browser to behave otherwise as long as your frontend code is trying to hit that API endpoint directly.

    So the only solution is to not hit that API endpoint directly from your frontend code but to instead either set up a proxy and change your frontend code to make the request through that, or else just handle it in some other way in your existing backend code, as mentioned above.

    The answer at Why does my JavaScript code receive a "No 'Access-Control-Allow-Origin' header is present on the requested resource" error, while Postman does not? gives some details on how you can set up a special CORS proxy, if you want to go that route.