I have a single page React application. I'm trying to authorize against Salesforce. I created a connected app inside of Salesforce and have a client_id
and client_secret
.
I originally tried using the library oidc-client-ts
to handle my authentication flow. However, every example I can find, shows them explosing the client_secret
on the client.
It seems every resource on single page authentication is handling it wrong. What is the point of it being a secret if we are supposed to just place it directly in our front end code?
Shouldn't the process be:
- Request code from identity provider with pkce and redirect uri
- Identity provider generates code and sends it to the redirect uri
- Redirect uri is a server-side endpoint that takes the code, and exchanges it for an authentication token by calling the identity provider with the code and
client_secret
- The server then receives the authentication token and redirects back to the client application
What am I missing?
PUBLIC CLIENTS
The
oidc-client-ts
library is a pure JavaScript SPA solution, for SPAs that do not use a client secret or backend client. When using it the SPA is a public client. A standards-based authorization server should support this option, but some identity systems, eg Salesforce, may not.BACKEND FOR FRONTEND
To integrate with SalesForce you need to store the client secret in a backend component, as you indicate. There is nowhere secure to store the value in a browser.
Using a Backend for Frontend is considered a more secure flow these days, to limit the impact of XSS exploits by avoiding exposing the API credential (access token) to JavaScript code.
Such a backend can safely store a client secret. Yet this requires a more complex flow than that used by
oidc-client-ts
, due to an extra application cookie layer. They should be considered two distinct solutions.