[SalesForce] REST API OAuth2 CORS Issue

Problem:

I have a separate app, from which I want to allow the user to authorize sharing data with Salesforce. The user clicks a button on the site, which executes a Javascript function that makes a GET (or POST) request to my backend server. The backend server redirects the user to https://login.salesforce.com/services/oauth2/authorize (as recommended in https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_understanding_web_server_oauth_flow.htm) to initiate the OAuth2 flow. The trouble here is that the redirect is unsuccessful (the Salesforce authorization page is not shown), and I always get CORS errors in the browser console.

Specifically, these are the CORS errors I see:

1)

Access to XMLHttpRequest at 'https://login.salesforce.com/services/oauth2/authorize?response_type=code&client_id={clientId}&redirect_uri=https://{my_domain}.com/sendAbstractCode' (redirected from 'https://{my_domain}.com/oAuthLogin') from origin 'https://{my_domain}.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

Attempted Solutions:

I have whitelisted my domain (https://{my_domain}.com) in Salesforce, as described at https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/extend_code_cors.htm.

I have also tried adding all these headers (both in Javascript, as well as the Java request / response in my backend server code).

headers["Access-Control-Allow-Origin"] = "*";
headers["crossOrigin"] = "true";
headers["Access-Control-Allow-Headers"] = "Origin, Content-Type, X-Auth-Token";
headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
headers["Origin"] = "https://{my_domain}.com";

Btw, I can successfully do the authorization flow if the user clicks on an HTML "a" tag, which directly sends GET request without Javascript. But I need to send the request after some processing in Javascript.

Unsupported Flow?

I wonder if the below message (at https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/extend_code_cors.htm) actually means that Salesforce doesn't support what I'm trying to do.
enter image description here

Does anyone know if I'm just doing something wrong, or if Salesforce doesn't support this use case at all? If so, how am I supposed to do the OAuth2 flow, initiating from Javascript? Other similar situations (e.g. https://developer.salesforce.com/forums/?id=9060G000000XfhRQAS) point to using a proxy, but isn't my backend server acting as a proxy in my flow?

Best Answer

You need to redirect the browser to the login server. The process won't work with XMLHttpRequest/JavaScript, even if there was CORS, because it is inherently a browser-based flow. The correct order of operations for the OAuth2 Web Server flow is: redirect to Salesforce, user logs in and grants access, as necessary, Salesforce redirects back to your server, your server reads the "code" from the query string, and makes a request to the /token endpoint to finally receive an access token (and optional refresh token) that you will then use for future API calls.

Instead of trying to call the login page directly, just do this:

window.location = salesforceLoginUrl;

Your browser will then go to Salesforce to login, just as the anchor link did, and you can complete the process.