Use DPoP In A Browser App
On this page
This feature requires an Enterprise plan.
1.63.0
The FusionAuth JavaScript SDKs can bind access and refresh tokens to a key pair that the SDK generates in the browser. In DPoP mode, the SDK calls FusionAuth directly instead of a hosted backend. The SDK signs a proof for every request to FusionAuth and to your API. For background, see Demonstrating Proof-of-Possession (DPoP).
Before you start, you need:
- An Enterprise license on FusionAuth
1.63.0or later. - A browser app that logs in with the React SDK
2.7.0or later, the Angular SDK2.1.0or later, or the Vue SDK1.4.0or later.
Allow DPoP Requests From Your App#
In DPoP mode, the browser sends token requests straight to FusionAuth, with a DPoP header. Configure CORS so FusionAuth accepts those requests from your app's origin:
- In the Admin UI, navigate to Settings -> System -> CORS .
- Enable Enable CORS.
- In Allowed headers, add
dpop. The default list already includesAuthorizationandAccept. Keep both headers in the list. - In Allowed origins, add the origin of your app, such as
http://localhost:3000. - Click .
CORS settings apply to every Tenant and Application in the instance. For every CORS field, see the CORS Reference. To make the same change with the API, add dpop to systemConfiguration.corsConfiguration.allowedHeaders with the Update The System Configuration API.
Turn On DPoP Mode#
Set useDpop to true in the SDK configuration. The following example shows the React SDK:
const config: FusionAuthProviderConfig = { clientId: 'e9fdb985-9173-4e01-9d73-ac2d60d1dc8e', redirectUri: 'http://localhost:3000', serverUrl: 'http://localhost:9011', scope: 'openid email profile offline_access', shouldAutoRefresh: true, useDpop: true,};The SDK generates the key pair, signs proofs for the token and refresh requests, and stores the tokens. Set dpopTokenStorage to choose where the SDK stores tokens. localStorage, the default, keeps the user logged in across page reloads. memory clears the tokens on reload. The Angular and Vue SDKs use the same options. See the DPoP Mode section of each SDK page for the exact syntax.
Call Your API#
Use dpopFetch to call your API. dpopFetch adds the access token and a new proof to each request:
const { dpopFetch } = useFusionAuth();
const response = await dpopFetch('https://api.example.com/data', { method: 'GET' });
For an HTTP library such as axios, call generateProof and getAccessToken, then set the Authorization and DPoP headers yourself:
const { generateProof, getAccessToken } = useFusionAuth();
const accessToken = getAccessToken();
const proof = await generateProof('https://api.example.com/data', 'GET', accessToken);
await axios.get('https://api.example.com/data', {
headers: { Authorization: `DPoP ${accessToken}`, DPoP: proof },
});
Pass the exact URL and method of the request to generateProof. Your API rejects a proof for a different URL or method.
Your API must check each proof. See Validate DPoP Requests In Your API.
Confirm Tokens Are Bound#
To confirm that FusionAuth bound the tokens:
- Open your browser's developer tools and log in to your app.
- Find the
POSTrequest to/oauth2/token. The request includes a DPoP header. - In the response, check that
token_typeisDPoP. - Decode the
access_tokenand check for acnfclaim with ajktvalue.
Troubleshooting#
When login fails after you turn on DPoP mode, check the browser console and the token response:
- A CORS error on
/oauth2/tokenmeans the DPoP header or your app's origin is missing from the CORS configuration. - A
not_licensederror means the instance doesn't have an active Enterprise license. - An
invalid_dpop_prooferror means FusionAuth rejected the proof. Check thatserverUrlmatches the URL FusionAuth sees for the request. Behind a proxy, FusionAuth needs theX-Forwarded-*headers to build that URL. See Proxy Setup. Also check that the clock on the user's device is within 15 seconds of the FusionAuth server clock.
Related
Learn how to check DPoP proofs and DPoP-bound FusionAuth access tokens in your API.
Learn how DPoP binds FusionAuth access and refresh tokens to a key pair that only your client holds.
Explore step-by-step single-page application QuickStart guides from FusionAuth to seamlessly integrate authentication into your application.
Learn about FusionAuth and Cross-Origin Resource Sharing (CORS) configuration.