0

I need to request an authorization code so my application can make a simple request to salesforce. Hitting the url in the article redirects me to the right page where I can grab the code, but I first need to be logged in to salesforce in order to get there.

So my question is, how can I grant my app access to reach this page?

I have tried installing base 64 and passing log in credentials as headers with a fetch request like this:

const username = 'username'
const password = 'password'

let base64 = require('base-64');

await fetch(`https://login.salesforce.com/services/oauth2/authorize?client_id=${this.state.client_id}&redirect_uri=${this.state.redirect_uri}&response_type=code`,
    {method:'GET',
        headers: {
          'Content-Type': 'text/json',
          'Authorization': 'Basic' + base64.encode(username + ":" + password)
        },
    })
    .then(response => response.json())
    .then(json => console.log(json));

I have also tried installing jsforce and dotenv, creating a connection and then passing the credentials through as environment variables like this:

const jsforce = require('jsforce');
require('dotenv').config();
const { REACT_APP_SF_USERNAME, REACT_APP_SF_PASSWORD, REACT_APP_SF_TOKEN, REACT_APP_SF_LOGIN_URL } = process.env

const conn = new jsforce.Connection({
    loginUrl: REACT_APP_SF_LOGIN_URL
});
conn.login(REACT_APP_SF_USERNAME, REACT_APP_SF_PASSWORD + REACT_APP_SF_TOKEN, err => {
    if (err) {
        console.error(err, 'there has been an error');
    }
});

However both methods result in a cors error:

Access to fetch at 'url' from origin 'https://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request.

or

Access to XMLHttpRequest at 'https://login.salesforce.com/services/Soap/u/42.0' from origin 'https://localhost:3000' has been blocked by CORS policy: Request header field soapaction is not allowed by Access-Control-Allow-Headers in preflight response.

I am even running my app via https local using mkcert so I know that isn't the cause of the issue.

Does anyone know a way I can get this to work, or alternatively is there a way I can bypass salesforce login somehow by giving my app a permission set?

7
  • 1
    The oauth authorize service should always be accessible, and specifically when you're not logged in. After all, what it is actually doing is allowing the user to do that login. I'm not clear what the problem actually is because what you've said here doesn't really make sense.
    – Phil W
    Jun 25 '21 at 9:54
  • Hi Phil, thanks for responding. I have applied my consumer id and redirect uri from my connected app as parameters to the url in the linked article. When I then visit that url I am redirected to a page that stores the code I need as a parameter in its own url. The problem I have is if I try to reach that page when I'm not logged in I need to enter my credentials in order to access the page. So I need a way to give my app authorisation to reach this page so I can take the code and pass it into my api call Jun 25 '21 at 10:04
  • I guess another question could be, how can I request the authorisation code using javascript? Is there another way of acquiring one, other than hitting that url? Jun 25 '21 at 10:31
  • Still not really clear what you're doing here, but take a look at this blog posting for some help with parsing a URL you receive. Your callback URL for OAuth2 gets invoked with the necessary values. Just make sure this is part of your React app...?
    – Phil W
    Jun 25 '21 at 10:42
  • Thanks. Trouble is I'm not receiving the url that I need because my request gets blocked by authentication Jun 25 '21 at 10:47
0

The solution I found was to bypass the need for an authorisation code by making grant_type equal to password, and including username and password in my request for an access token like this:

POST /services/oauth2/token HTTP/1.1
Content-type: application/x-www-form-urlencoded
grant_type=password&
client_id={consumer id}&
client_secret={client secret}&
username={username}&
password={password}

Access token gets returned in the same way. Hope this helps someone out in the future

5
  • Do not use this for production code. This is specifically called out in the documentation. Also, if you plan on listing your app, you'll fail the Security Review using this method.
    – sfdcfox
    Jun 25 '21 at 14:20
  • I came across this method in the documentation Jun 25 '21 at 15:20
  • That's only for IoT. The main documentation states: However, we recommend avoiding this flow because it passes credentials back and forth. Use it only if there’s a high degree of trust between the resource owner and the client, the client is a first-party app, Salesforce is hosting the data, and other grant types aren’t available. In these cases, set user permissions to minimize access and protect stored credentials from unauthorized access.
    – sfdcfox
    Jun 25 '21 at 15:38
  • 1
    If you require no interaction, go with OAuth 2.0 JWT Bearer Flow for Server-to-Server Integration.
    – sfdcfox
    Jun 25 '21 at 15:38
  • Perfect! This is exactly what I needed. Thank you so much Jun 26 '21 at 8:59
0

Use the OAuth 2.0 Web Server Flow for Web App Integration. You start by redirecting the user to:

https://login.salesforce.com/services/oauth2/authorize?client_id=3MVG9IHf89I1t8hrvswazsWedXWY0i1qK20PSFaInvUgLFB6vrcb9bbWFTSIHpO8G2jxBLJA6uZGyPFC5Aejq&redirect_uri=https://www.mycustomerorderstatus.com/oauth2/callback&response_type=code

Where client_id is your Connected App's Client Id, the redirect_uri is the endpoint configured in your Connected App (you can use localhost for development purposes). After a user authenticates, they will be redirected back to your app at the redirect URI you specify, with a code:

https://localhost/oauth2/callback?code=aPrx4sgoM2Nd1zWeFVlOWveD0HhYmiDiLmlLnXEBgX01tpVOQMWVSUuafFPHu3kCSjzk4CUTZg==

Which you then exchange for an access token:

POST /services/oauth2/token HTTP/1.1
Host: mycompany.my.salesforce.com
Content-length: 307
Content-type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=aPrxhgZ2MIpkSy0aOdn07LjKFvsFOis6RGcWXz7p8JQCjcqfed5NQLe7sxWwMY_JQFuLwHRaRA==&
client_id=3MVG9IHf89I1t8hrvswazsWedXWY0iqK20PSFaInvUgLFB6vrcb9bbWFTSIHpO8G2jxBLJA6uZGyPFC5Aejq&
client_secret=*******************&
redirect_uri=https://www.mycustomerorderstatus.com/oauth2/callback

This will give you a proper access token, and prevent any security problems by having your app directly handling usernames and passwords.

Note that if you're using the Password OAuth flow in production code, your Connected App may be blocked as a security precaution. Again, don't do this in production code.

2
  • I need to find a way that does not require any user interaction though Jun 25 '21 at 14:42
  • @sgt_pepper85 If this is an integration user, the integration user can log in via that flow or JWT flow. Those methods are relatively secure compared to the username-password flow.
    – sfdcfox
    Jun 25 '21 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.