REST API OAuth2 CORS Issue
up vote
2
down vote
favorite
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.
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
New contributor
add a comment |
up vote
2
down vote
favorite
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.
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
New contributor
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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.
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
New contributor
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.
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
javascript oauth2 authentication browser cors
New contributor
New contributor
edited 3 hours ago
New contributor
asked 3 hours ago
user1145925
1134
1134
New contributor
New contributor
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
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.
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
2 hours ago
1
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
add a comment |
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',
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
up vote
2
down vote
accepted
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.
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
2 hours ago
1
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
add a comment |
up vote
2
down vote
accepted
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.
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
2 hours ago
1
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
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.
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.
edited 2 hours ago
answered 2 hours ago
sfdcfox
245k10185418
245k10185418
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
2 hours ago
1
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
add a comment |
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
2 hours ago
1
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
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
2 hours ago
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
2 hours ago
1
1
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
@user1145925 Yes, that makes sense. You simply aren't allowed to call the login site directly in an OAuth2 flow.
– sfdcfox
2 hours ago
add a comment |
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.
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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