I can’t solve the implementation of refresh tokens, my backend is OK at PostMan works OK, with a curl command it’s OK too, I send the header with a refresh token and the backend responses with an object with an accessToken that works ok too, but when I use the frontend the error is a 401! Please help me.!
This is the Interceptor:
export const customInterceptor: HttpInterceptorFn = (req, next) => {
const excludedRoutes = ['/login']; // Customizable array
const shouldExclude = excludedRoutes.some(route => req.url.includes(route));
const authService = inject(AuthService);
if (shouldExclude) {
return next(req);
}
const token = authService.getAuthToken();
const cloneRequest = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next(cloneRequest).pipe(
catchError((error) => {
if (error.status === 401) {
console.log("From the interceptor, here is the error: " + error.status);
return authService.refreshToken().pipe(
switchMap((res) => {
localStorage.setItem('authToken', res.accessToken);
console.log("From the interceptor, the new authToken is: " + res.accessToken);
const newReq = req.clone({
setHeaders: {
Authorization: `Bearer ${res.accessToken}`
}
});
return next(newReq);
}),
catchError((refreshErr) => {
const finalError = new Error(refreshErr);
console.log("Error refreshing the token", finalError);
authService.logout();
return throwError(() => new Error('Session expired, please log in again'));
})
);
} else {
// Handle other errors (e.g., network errors)
return throwError(() => error);
}
})
);
};
This is the service method:
refreshToken() {
const refreshToken = localStorage.getItem('refreshToken');
console.log("The refreshToken inside the method is: " + refreshToken);
if (!refreshToken) {
throw new Error('Refresh token missing');
}
console.log("Sending refresh token to backend: " + refreshToken);
return this._httpClient.post<any>(`${this.baseURL}/refresh`, {}, {
headers: {
Authorization: `Bearer ${refreshToken}`
}
}).pipe(
catchError((error) => {
console.error("Refresh token error:", error);
return throwError(() => new Error("Refresh error"));
})
);
}
Gustavo Starace is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
It seems like your customInterceptor is mostly set up correctly, but there might be a few reasons why you’re getting a 401 error in your Angular frontend:
Token Synchronization Issue: There might be an issue where the interceptor tries to use the old token even after getting the new one.
Interceptor Chaining Issue: If multiple interceptors are registered, they may not handle the 401 error correctly, causing the token refresh to not propagate properly.
API Request Timing: The token refresh might not have completed before the new request is made.
Angular’s HttpInterceptorFn Syntax: If you are using Angular 16+ with the HttpInterceptorFn function type, ensure the setup is correctly implemented.
tried this code :
export const customInterceptor: HttpInterceptorFn = (req, next) => {
const excludedRoutes = ['/login']; // Exclude login endpoint from interception
const shouldExclude = excludedRoutes.some(route => req.url.includes(route));
const authService = inject(AuthService);
if (shouldExclude) {
return next(req);
}
const token = authService.getAuthToken();
let cloneRequest = req;
if (token) {
cloneRequest = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
}
return next(cloneRequest).pipe(
catchError((error) => {
if (error.status === 401) {
// Token is expired or invalid, try refreshing the token
return authService.refreshToken().pipe(
switchMap((res) => {
// Store new access token
localStorage.setItem('authToken', res.accessToken);
// Clone the request with new token and resend it
const newReq = req.clone({
setHeaders: {
Authorization: `Bearer ${res.accessToken}`
}
});
// Continue the request with the new token
return next(newReq);
}),
catchError((refreshErr) => {
// Refresh token failed, handle logout or other error
console.log("Error refreshing the token:", refreshErr);
authService.logout(); // Redirect to login or handle logout
return throwError(() => new Error('Session expired, please log in again'));
})
);
} else {
// For any other errors
return throwError(() => error);
}
})
);
};
In authService :
refreshToken() {
const refreshToken = localStorage.getItem('refreshToken');
console.log("The refreshToken inside the method is: " + refreshToken);
if (!refreshToken) {
throw new Error('Refresh token missing');
}
return this._httpClient.post<any>(`${this.baseURL}/refresh`, {}, {
headers: {
Authorization: `Bearer ${refreshToken}`
}
}).pipe(
catchError((error) => {
console.error("Refresh token error:", error);
return throwError(() => new Error("Refresh error"));
})
);
}