function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
jhartjhart 

Please support the sandbox via login.salesforce.com

This post talks about OAuth, but the exact same issues apply for username + password
interactions.

Salesforce has multiple instances on the backend, but uses a single "front door" for

logins (login.salesforce.com).  After successful login, you are sent to the right instance
to connect to (na15.salesforce.com, cs1.salesforce.com, etc).  At the user level
this is handled with a simple redirect; at the API level this is information passed
back in the login response.

HOWEVER, that top level unified domain only works for production logins.  Sandbox
logins have to use a different domain (test.salesforce.com), even though there
are *many* situations in which the calling code cannot possibly know which domain
to use.


As an example, let's say you want OAuth support in your API client app.

The first step in the OAuth flow is sending the user to a special page at which
they can OK access by your app.  You need to be able to determine if the user
is sandbox or not, because if they are, the initial "approve access" URL is
different:

 

normal: https://login.salesforce.com/services/oauth2/authorize
sandbox: https://test.salesforce.com/services/oauth2/authorize

This is annoying but surmountable - given that you are already interacting with the user,
you can probably figure out some hamfisted way of determing which URL to send them to.

But the next step is totally opaque.

The user authorizes access, and is redirect to your redirect_uri.  Your redirect_uri
is given a single parameter ("code") for the next call to "authorization_code".

In other words, your redirect_uri page is given zero indication of whether the given
code is used in the sandbox or not.

The only solution is to try to the "authorization_code" on the production URL, and if
that fails, cache the error & try the sandbox URL.  If that works, great, you know
it's a sandbox situation.  If try #2 fails, you now have two errors, and you need
to arbitrate amongst them to decide which to bubble up to the user.

 

(Note there is a totally nasty hack to guess sandbox vs. production - you could
look at the HTTP "Referrer" header, and hope that it's present & correct, and
then perform some mapping by which you hardcode that "cs4.salesforce.com" is
sandbox but "na3.salesforce.com" is production...  I do not count this is a
robust solution)

Given that the entire point of "login.salesforce.com" is to provide a single
"front door" that then tells you which actual domain to use, why don't sandbox
logins use the exact same front door?  Using "test.salesforce.com" for logins
means that client apps that wish to support the sandbox are needlessly complex.



Edit: it is possible to pass a "state" parameter to the oauth login page, and that will get passed back

to the redirect_uri, so one can detect sandbox prior to sending the user to the login page, and then

encode that knowledge into the "state" parameter so the redirect_uri knows.  It's a solution for this

particular case, but in general having to decide ahead of time on the "front door' endpoint means

that everyone who does an integration has to cart around extra data about each oauth token

(ie, whether it is sandbox or not). Still seems like a design bug.

Kai MederKai Meder
this. +1