3

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?

1 Answer 1

3

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.

2
  • So, I think I should try the following. First, Javascript sends request to my backend server. Backend server tries to GET the data from Salesforce API if the user's accessToken already exists. If not, then, in Javascript callback, I set the window.location as you suggest, allowing the user to authorize Salesforce to share data. Does that make sense? Commented Dec 16, 2018 at 22:26
  • 1
    @user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
    – sfdcfox
    Commented Dec 16, 2018 at 22:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .