I wrote an Interceptor to refresh token for me. But with the debugger I checked, it doesn't enter switchMap at all, and the request doesn't send it again. Does anyone know where the problem comes from?
import {HttpErrorResponse, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from '@angular/common/http';
import {Injectable, Injector} from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import {catchError, switchMap, tap} from 'rxjs/operators';
import {ResponseModel} from '../Models/responseModel';
import {UserDataModel} from '../Models/UserDataModel';
import {RoleEnum} from '../Enums/RoleEnum';
import {AuthService} from '../../auth/auth.service';
import {AuthModel} from '../Models/authModel';
import {LoginType} from '../Enums/LoginType';
import {LoginResponseModel} from '../Models/LoginResponseModel';
@Injectable({providedIn: 'root'})
export class TokenInterceptor implements HttpInterceptor {
httpSubject: BehaviorSubject<LoginResponseModel> = new BehaviorSubject<LoginResponseModel>(null);
constructor(private injector: Injector) {
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
let modifiedReq;
const userData: {
username: string,
access_token: string,
refresh_token: string,
role: RoleEnum,
_tokenexpirationDate: string
} = (JSON.parse(localStorage.getItem('userData')));
if (userData.access_token !== null && !req.headers.has('X-Skip-Interceptor')) {
modifiedReq = req.clone({
headers: req.headers.set('access_token', `${userData.access_token}`),
});
} else {
modifiedReq = req.clone({
setHeaders: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
}
});
}
return next.handle(modifiedReq).pipe(tap(res => {
if (res instanceof HttpResponse) {
const response = (<HttpResponse<ResponseModel<string>>> res).body;
/*const userdata: {
username: string,
access_token: string,
refresh_token: string,
role: RoleEnum,
_tokenexpirationDate: string
} = (JSON.parse(localStorage.getItem('userData')));*/
if (!response.is_successfull) {
if (new Date() > new Date(userData._tokenexpirationDate)) {
this.refreshToken(req, next, userData.refresh_token, userData.username);
}
}
}
}));
}
refreshToken(req: HttpRequest<any>, next: HttpHandler, refreshtoken: string, username: string) {
this.httpSubject.next(null);
const authService = this.injector.get(AuthService);
const authmodel: AuthModel = {
email_address: '', grant_type: LoginType.RefreshToken, password: '', phone_number: '', phone_number_countery_iso2_code: '',
refresh_token: refreshtoken, username: ''
};
debugger;
return authService.Signin(authmodel).pipe(
switchMap(result => {
debugger;
if (result.is_successfull && result.response.access_token !== null) {
const expirationDate = new Date(new Date().getTime() + +result.response.expires_in * 60000);
const user = new UserDataModel(username, result.response.access_token, result.response.refresh_token
, result.response.role, expirationDate);
localStorage.setItem('userData', JSON.stringify(user));
this.httpSubject.next(result.response);
req = req.clone({
setHeaders: {
access_token: `${result.response.access_token}`
}
});
return next.handle(req);
}
}) , catchError(err => {
console.log(err);
return Observable;
}));
}
}
I would also like to say that if I use subscribe instead of pipe, switchMap, the token will be refreshed and only the request will not be repeated from the beginning.