|
6 | 6 | - [Display the user profile](#display-the-user-profile) |
7 | 7 | - [Protect a route](#protect-a-route) |
8 | 8 | - [Call an API](#call-an-api) |
| 9 | +- [Wrapping the interceptor for granular control](#wrapping-the-interceptor-for-granular-control) |
9 | 10 | - [Handling errors](#handling-errors) |
10 | 11 | - [Organizations](#organizations) |
11 | 12 | - [Device-bound tokens with DPoP](#device-bound-tokens-with-dpop) |
@@ -290,6 +291,66 @@ AuthModule.forRoot({ |
290 | 291 |
|
291 | 292 | You might want to do this in scenarios where you need the token on multiple endpoints, but want to exclude it from only a few other endpoints. Instead of explicitly listing all endpoints that do need a token, a uriMatcher can be used to include all but the few endpoints that do not need a token attached to its requests. |
292 | 293 |
|
| 294 | +## Wrapping the interceptor for granular control |
| 295 | +
|
| 296 | +While the `allowedList` configuration and `uriMatcher` provide flexible ways to control which requests receive access tokens, there may be scenarios where you need even more granular control on a per-request basis. For example: |
| 297 | +
|
| 298 | +- Conditionally attaching tokens based on runtime state (not just URL patterns) |
| 299 | +- Using HttpContextTokens to bypass the interceptor for specific requests |
| 300 | +- Implementing environment-specific behavior (e.g., skip authentication in development) |
| 301 | +- Making the same request with and without a token based on user actions |
| 302 | +
|
| 303 | +In these cases, you can wrap the `authHttpInterceptorFn` in your own custom interceptor: |
| 304 | +
|
| 305 | +```ts |
| 306 | +import { HttpRequest, HttpHandlerFn, HttpEvent, HttpContextToken } from '@angular/common/http'; |
| 307 | +import { authHttpInterceptorFn } from '@auth0/auth0-angular'; |
| 308 | +import { Observable } from 'rxjs'; |
| 309 | + |
| 310 | +export function customAuthInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> { |
| 311 | + // Implement shouldByPassAuth logic based on your needs |
| 312 | + if (shouldByPassAuth(req)) { |
| 313 | + return next(req); |
| 314 | + } |
| 315 | + |
| 316 | + // Otherwise, use the standard auth interceptor |
| 317 | + return authHttpInterceptorFn(req, next); |
| 318 | +} |
| 319 | +``` |
| 320 | +
|
| 321 | +Register your custom interceptor instead of the built-in one: |
| 322 | +
|
| 323 | +```ts |
| 324 | +import { provideHttpClient, withInterceptors } from '@angular/common/http'; |
| 325 | +import { bootstrapApplication } from '@angular/platform-browser'; |
| 326 | +import { provideAuth0 } from '@auth0/auth0-angular'; |
| 327 | + |
| 328 | +bootstrapApplication(AppComponent, { |
| 329 | + providers: [ |
| 330 | + provideAuth0({ |
| 331 | + domain: 'YOUR_AUTH0_DOMAIN', |
| 332 | + clientId: 'YOUR_AUTH0_CLIENT_ID', |
| 333 | + authorizationParams: { |
| 334 | + audience: 'YOUR_AUTH0_API_IDENTIFIER', |
| 335 | + }, |
| 336 | + httpInterceptor: { |
| 337 | + allowedList: ['/api/*'], // Configure as needed |
| 338 | + }, |
| 339 | + }), |
| 340 | + provideHttpClient(withInterceptors([customAuthInterceptor])), |
| 341 | + ], |
| 342 | +}); |
| 343 | +``` |
| 344 | +
|
| 345 | +### Important: allowedList still applies |
| 346 | +
|
| 347 | +**When you wrap the interceptor, any request that you pass through to `authHttpInterceptorFn` must still match the `allowedList` configuration.** If a request doesn't match the `allowedList` (or the configured glob patterns), the Auth0 interceptor will not add a token to that request, even if you intended it to. |
| 348 | +
|
| 349 | +This means: |
| 350 | +
|
| 351 | +- If you bypass a request in your wrapper (e.g., using `AUTH_INTERCEPTOR_BYPASS`), it will never reach `authHttpInterceptorFn`, so the `allowedList` doesn't matter for that request. |
| 352 | +- If you pass a request through to `authHttpInterceptorFn`, ensure its URL matches your `allowedList` configuration, otherwise no token will be added. |
| 353 | +
|
293 | 354 | ## Handling errors |
294 | 355 |
|
295 | 356 | Whenever the SDK fails to retrieve an Access Token, either as part of the above interceptor or when manually calling `AuthService.getAccessTokenSilently` and `AuthService.getAccessTokenWithPopup`, it will emit the corresponding error in the `AuthService.error$` observable. |
|
0 commit comments