My backend is Django restframework. when I give my credentials it gives me tokens which are consist of refresh and access tokens. In my backend my access_tokens expiration time is 2 minutes(just for testing but will increase till 15 minutes). and refresh_tokens expiration time is 15 days. when my access_token expires I send my refresh_token to fetch new access_token(only provides access_token).
On front_end (Angular 17), I have implemented to fetch the new access_tokens instead of getting new tokens I am getting logout after 2 minutes.
I am new to Angular. I tried to debug but couldn’t find the solution. I am posting my service class and interceptor.
export const authInterceptor: HttpInterceptorFn = (req, next) => {
const auth_service = inject(AuthService);
const accessToken = auth_service.getAccessToken();
let authReq = req;
if (accessToken)
{
authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${accessToken}`
}
});
}
return next(authReq).pipe(
catchError((error: HttpErrorResponse) => {
if (error.status === 401 && error.error.code === 'token_not_valid') {
console.log('Token expired, attempting to refresh...');
// Token expired, attempt to refresh
return auth_service.refreshTokenRequest().pipe(
switchMap(() => {
const newAccessToken = auth_service.getAccessToken();
if (newAccessToken) {
console.log('New access token received');
authReq = req.clone({
setHeaders: {
Authorization: `Bearer ${newAccessToken}`
}
});
}
return next(authReq);
}),
catchError((err) => {
console.error('Token refresh failed:', err);
auth_service.logout();
return throwError(() => err);
})
);
}
return throwError(() => error);
})
);
};
and my service class is
export class AuthService {
constructor() { }
http = inject(HttpClient);
router = inject(Router);
private apiUrl = 'http://localhost:8000/api/v1/';
private jwtHelper = new JwtHelperService();
private accessToken: string | null = null;
private refreshToken: string | null = null;
private isAuthenticatedSubject = new BehaviorSubject<boolean>(false);
storeJWTToken(token: any): void
{
localStorage.setItem('access_token', token.access);
localStorage.setItem('refresh_token', token.refresh);
if (token.access)
this.accessToken = token.access;
if (token.refresh)
this.refreshToken = token.refresh;
this.isAuthenticatedSubject.next(true);
}
login(user: User) : Observable<any>
{
return this.http.post<any>(this.apiUrl + 'login/', user)
.pipe(tap(response => {
console.log('tokens:', response.access);
this.storeJWTToken(response);
}))
;
}
logout(): void {
try
{
localStorage.removeItem('access_token');
localStorage.removeItem('refresh_token');
this.isAuthenticatedSubject.next(false);
this.router.navigate(['/login']);
}
catch (error)
{
console.error('Error while logging out:', error);
}
}
isLoggedIn()
{
const Token = this.getAccessToken();
return Token ? !this.jwtHelper.isTokenExpired(Token) : false;
}
isAuthenticated() : boolean
{
const token = this.accessToken || localStorage.getItem('access_token');
return token ? !this.jwtHelper.isTokenExpired(token) : false;
}
getAccessToken() : string | null
{
return this.accessToken || localStorage.getItem('access_token');
}
refreshTokenRequest() : Observable<any>
{
const refreshToken = this.refreshToken || localStorage.getItem('refresh_token');
if (!refreshToken)
return throwError(() => new Error('No refresh token found'));
return this.http.post<any>(this.apiUrl + 'login/refresh/', {refresh: refreshToken})
.pipe(tap(response => {
this.accessToken = response.access;
if (this.accessToken)
localStorage.setItem('access_token', this.accessToken);
})
);
}
}
I have tried that but still not able to find the problem.
and my app.config.ts file is
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideAnimationsAsync(),
provideHttpClient(
withXsrfConfiguration({
cookieName: 'csrftoken',
headerName: 'X-CSRFToken',
}),
withInterceptors([authInterceptor]),
),
importProvidersFrom([
JwtModule.forRoot({
config: {
tokenGetter: () => localStorage.getItem('access_token')
}
})
]),
]
};