Working with Salesforce authorization

To integrate your OpenFin app with Salesforce’s REST APIs it must first get authorization by using the OAuth 2.0 web server flow, which implements the OAuth 2.0 authorization code grant type.

OpenFin’s Salesforce integration implements the PKCE OAuth 2.0 flow (Proof Key for Code Exchange, pronounced "pixy"), which provides secure authorization without needing to expose a sensitive client secret to insecure clients. To guard against potential XSS vulnerabilities, OpenFin’s integration includes a web worker that handles authorization tokens and remote requests that involve tokens.

📘

Note

The Web workers API provides what are essentially background threads — that is, they run in a context that is different from the parent app’s thread. This means the code running in the parent app cannot access code running in the web worker and vice versa. The only way a web worker and the parent app communicate is by exchanging messages, and if the web worker never leaks tokens through messages, we can consider the tokens secure from XSS.

The authorization process

Whenever the connect function is called from the Salesforce integration API, a hidden child window is created and navigated to the authorization endpoint that starts the OAuth 2.0 web server flow. This window might then be displayed to the user if any of the following is true:

  • The user is not already authenticated with Salesforce.

  • Your app is not already authorized to use all of the requested scopes.

  • An invalid parameter was passed to the authorization flow, or some other authorization error occurred.

📘

Note

Authorization can fail for a number of reasons. Refer to the Salesforce documentation for more information on the kinds of authorization errors you may encounter.

If the current user is authenticated and the app is authorized for the requested scopes, the window is redirected to a predefined URL where it receives an authorization code. The Salesforce integration API then closes the window and exchanges the code for an access token (for making REST API requests) and a refresh token (for renewing expired access tokens).

At this point, the authorization process has completed successfully and requests can now be made to Salesforce’s REST APIs.

Token lifetimes

Access tokens are typically valid for only a couple of hours for security reasons, while refresh token lifetimes can be configured by updating the refresh token policy for the Connected App.

🚧

Warning

Change the default refresh token expiration policy.

By default, the refresh token policy for a Connected App is set to never expire. We recommend changing this setting, as refresh tokens can present a security issue if inadvertently leaked. To mitigate this risk, OpenFin recommends setting the refresh token policy to expire after 1 day.",

Handle token expiration

If a request is made to the Salesforce REST API and the current access token has expired, the Salesforce integration API automatically requests a new access token using the refresh token (stored in memory by the web worker). If this fails (for example, if the refresh token has expired), then a AuthTokenExpiredError is thrown and the connect function must be called again to start the authorization process in order to retrieve new access and refresh tokens.

Whenever you call executeApiRequest, be sure to always catch errors and check to see whether the error is an AuthTokenExpiredError. That way you can handle re-connection in the most ideal way for your users and particular environment configuration:

import { AuthTokenExpiredError } from '@openfin/salesforce';

try {
  const response = await salesforceConnection.executeApiRequest('/services/data/v56.0/sobjects/Account');
  // Do something with the response...
} catch (err) {
  if (err instanceof AuthTokenExpiredError) {
    // Need to reconnect...
  } else {
    throw err;
  }
}