REST API OAuth2 CORS Issue












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?










share|improve this question









New contributor




user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

























    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?










    share|improve this question









    New contributor




    user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.























      3












      3








      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?










      share|improve this question









      New contributor




      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      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?







      javascript oauth2 authentication browser cors






      share|improve this question









      New contributor




      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited Dec 16 at 21:27





















      New contributor




      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked Dec 16 at 21:16









      user1145925

      1184




      1184




      New contributor




      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      user1145925 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






















          1 Answer
          1






          active

          oldest

          votes


















          2














          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.






          share|improve this answer























          • 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?
            – user1145925
            Dec 16 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
            Dec 16 at 22:33











          Your Answer








          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "459"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          user1145925 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f243776%2frest-api-oauth2-cors-issue%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          1 Answer
          1






          active

          oldest

          votes








          1 Answer
          1






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          2














          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.






          share|improve this answer























          • 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?
            – user1145925
            Dec 16 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
            Dec 16 at 22:33
















          2














          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.






          share|improve this answer























          • 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?
            – user1145925
            Dec 16 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
            Dec 16 at 22:33














          2












          2








          2






          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.






          share|improve this 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.







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Dec 16 at 22:18

























          answered Dec 16 at 22:11









          sfdcfox

          246k11186423




          246k11186423












          • 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?
            – user1145925
            Dec 16 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
            Dec 16 at 22:33


















          • 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?
            – user1145925
            Dec 16 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
            Dec 16 at 22:33
















          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?
          – user1145925
          Dec 16 at 22:26




          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?
          – user1145925
          Dec 16 at 22:26




          1




          1




          @user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
          – sfdcfox
          Dec 16 at 22:33




          @user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
          – sfdcfox
          Dec 16 at 22:33










          user1145925 is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          user1145925 is a new contributor. Be nice, and check out our Code of Conduct.













          user1145925 is a new contributor. Be nice, and check out our Code of Conduct.












          user1145925 is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Salesforce Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f243776%2frest-api-oauth2-cors-issue%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          數位音樂下載

          When can things happen in Etherscan, such as the picture below?

          格利澤436b