My environment & features of my application/project: Angular 19 and .Net Backend, getting videos data from Youtube and login and register feature with http_interceptors.
My problem or my issue: my query api to Youtube is not working if i am using http_interceptors in main.ts. This is how I test it: I comment the http_interceptors then my query api is working as it supposed to.
my http_interceptor in main.ts:
{
provide: HTTP_INTERCEPTORS,
useClass: JwtInterceptor,
multi: true
},
my error from get HTTP and subscription from Youtube:
{
"headers": {
"normalizedNames": {
},
"lazyUpdate": null
},
"status": 401,
"statusText": "OK",
"url": "https://www.googleapis.com/youtube/v3/playlistItems?key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&part=snippet&maxResults=12&playlistId=PLPvjlyTckx7OhGYE9JZw9Q1MYP_n-u-8V",
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure response for https://www.googleapis.com/youtube/v3/playlistItems?key=xxxxxxxxxxxxxxxxxxxxxxxx&part=snippet&maxResults=12&playlistId=PLPvjlyTckx7OhGYE9JZw9Q1MYP_n-u-8V: 401 OK",
"error": {
"error": {
"code": 401,
"message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
"errors": [
{
"message": "Invalid Credentials",
"domain": "global",
"reason": "authError",
"location": "Authorization",
"locationType": "header"
}
],
"status": "UNAUTHENTICATED"
}
}
}
my JwtInterceptor code in component:
export class JwtInterceptor implements HttpInterceptor {
private accountService = inject(AccountService);
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
this.accountService.user$.pipe(take(1)).subscribe({
next: user => {
if (user) {
// Clone from the coming request and add Authorization header to that
request = request.clone({
setHeaders: {
Authorization: `Bearer ${user.jwt}`
}
});
}
}
})
return next.handle(request);
}
}
My question is: How I am to going disable the interceptor when I try to access or get data from Youtube?
Thanks.
You can modify your interceptor to return early if the request isn't headed for a domain that needs your JWT.
Here I've used a simple regex to check against a single domain, but any test to confirm whether or not you know the target URL requires the JWT would work:
export class JwtInterceptor implements HttpInterceptor {
private accountService = inject(AccountService);
private readonly myDomainPattern = /^http(s)?:[\/\\]{2}example.com[\/\\].*/i;
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
// If this request isn't going to our API, we don't need
// to append our JWT. Third party services won't need it.
if (!myDomainPattern.test(req.url)) {
return next.handle(request);
}
// Otherwise, continue adding our JWT as usual.
this.accountService.user$.pipe(take(1)).subscribe({
next: user => {
if (user) {
// Clone from the coming request and add Authorization header to that
request = request.clone({
setHeaders: {
Authorization: `Bearer ${user.jwt}`
}
});
}
}
})
return next.handle(request);
}
}
Side note, you might run into timing issues with your interceptor because you're returning after subscribing, not after the user$
observable emits.
You can return a composed observable that will delay executing next.handle()
until user$
has emitted:
// Otherwise, continue adding our JWT as usual.
return this.accountService.user$.pipe(
take(1),
switchMap(user => {
if (user) {
request = request.clone({
setHeaders: {
Authorization: `Bearer ${user.jwt}`,
}
});
}
return next.handle(request);
}));