This package contains middleware which authenticates to a Salesforce Connected App. Once authenticated, LWR app developers can make requests to their Salesforce org. The middleware works with both Express and Koa LWR server types.
Add the middleware to the LWR server:
// excerpt from /my-lwr-app/src/index.ts
import { createServer } from 'lwr';
import { platformWebServerAuthMiddleware } from '@lwrjs/auth-middleware';
const lwrApp = createServer(lwrConfig);
platformWebServerAuthMiddleware(lwrApp); // Pass in the generic LWR server
For more information on LWR middleware see this recipe.
Start the LWR server, and pass the Connected App information in using environment variables:
CLIENT_KEY=abc.123 CLIENT_SECRET=****** yarn start
Authenticate by accessing the /login
endpoint from the LWR app:
<!-- /my-lwr-app/src/modules/my/app/app.html -->
<a href="/login?app_path=%2Fhome">Login to Salesforce</a>
Make authenticated requests from the LWR app through the proxy endpoint:
// /my-lwr-app/src/modules/my/app/app.js
export default class MyApp extends LightningElement {
records;
getOpportunities() {
fetch('/services/data/v54.0/ui-api/list-ui/Opportunity/AllOpportunities')
.then((res) => {
res.json().then((data) => (this.records = data));
})
.catch((e) => {
console.error(e);
});
}
}
Before using the LWR authentication middleware, the app developer must set up a Connected App:
- Follow these instructions to set up the Connected App with OAuth enabled.
- Make selections for a "Web Server Flow" (not Device or JWT flows).
- Set the "Callback URL" to the origin of the LWR app with an
/oauth
path appended (e.g.https://website.com/oauth
).
- Make a note of the "Consumer Key" (i.e. Client ID) and "Consumer Secret" (i.e. Client Secret) (or find them later in the App Manager).
The platformWebServerAuthMiddleware
uses the OAuth 2.0 Web Server Flow for Web App Integration.
An app developer can attach the LWR authentication middleware when they create their LWR server. The middleware takes the following arguments:
-
Required LWR app instance from
createServer()
; this is compatible with both the Express and Koa LWR server types. Do not useLwrApp.getInternalServer()
, which returns either the underlying Express or Koa server. -
Optional bag of options:
{ proxyEndpoint?: string; }
:- proxyEndpoint: The endpoint which proxies all its requests to the Salesforce org; it defaults to
/services/data
.
- proxyEndpoint: The endpoint which proxies all its requests to the Salesforce org; it defaults to
import { createServer } from 'lwr';
import { platformWebServerAuthMiddleware } from '@lwrjs/auth-middleware';
const lwrApp = createServer(lwrConfig);
platformWebServerAuthMiddleware(lwrApp, { proxyEndpoint: '/some/where' });
In order to authenticate with the Web Server Flow, the following Connected App information is needed:
-
CLIENT_KEY
: The public OAuth identifier for the Connected App (i.e. "Consumer Key", "Client ID"). -
CLIENT_SECRET
: The password to go along with theCLIENT_KEY
(i.e. "Consumer Secret", "Client Secret"), known only to the Connected App the and LWR server.
This information is passed to the LWR server via environment variables to keep them secure and out of the codebase.
Read more about the OAuth Client ID and Secret here.
Additionally, the following optional environment variables are supported:
-
MY_DOMAIN
: The domain of the Salesforce org (Note: Find this in Setup -> "My Domain"; this is not necessarily the same as the URL in the browser address bar when visiting the org). If this is not set thenhttps://login.salesforce.com
will be used as the fallback login server. NOTE: if a login request has thelogin_server
query parameter set that overridesMY_DOMAIN
for that login request.
The LWR authentication middleware provides the following endpoints:
-
/login
: Accessed from the LWR app client code to trigger the OAuth flow and allow the current user to log in.- The
/login
endpoint takes an optional query parameter:app_path
. Setapp_path
to the path and parameters the LWR server should redirect to after authenticating (e.g./home
,/list?sort=desc
). If omitted,app_path
defaults to/
. This value must be URL encoded.
- The
-
/oauth
: Used internally as part of the OAuth flow, this is the OAuth redirect URI for the Connected App which fetches the OAuth token. -
/revoke
: Accessed from the LWR app client code to trigger a revoke of the access token. This should be called whenever a user logs out of the LWR app client. - proxy endpoint: Requests sent to this endpoint are proxied to the Salesforce org with the OAuth token in an Authorization header. By proxying these requests through the LWR server, the token remains secure from inspection by the client. The proxy endpoint is optionally passed into the
platformWebServerAuthMiddleware
as an option; the default proxy endpoint is/services/data
.
The LWR server takes the following steps in order to authenticate and make authorized requests to a Salesforce org:
- The LWR authentication middleware receives a request to its
/login
endpoint. - The middleware builds the
redirect_uri
by appending/oauth
to the origin. - The middleware redirects to the org's
/services/oauth2/authorize
endpoint to request an authorization code. - The user sees a login page in their browser and enters their username and password.
- The Connected app makes a request to the middleware's redirect URI (i.e. the
/oauth
endpoint) which includes the authorization code. - The middleware POSTs to the org's
/services/oauth2/token
endpoint to request an OAuth token. - Upon receiving the token, the middleware adds it to a secure
httpOnly
cookie and redirects to the LWR app (i.e.app_path
). - When the middleware receives a request to the proxy endpoint, it forwards the request to the Salesforce org authorized with the OAuth token:
headers = {
Authorization: `Bearer ${token}`,
};