为什么SwitchMap在角度拦截器(角度9)中不起作用 [英] why switchMap not working in Angular interceptor ( Angular 9 )
本文介绍了为什么SwitchMap在角度拦截器(角度9)中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我编写了一个拦截器来为我刷新令牌。但使用我检查的调试器,它根本不会进入SwitchMap,请求也不会再次发送它。 有人知道问题是从哪里来的吗?
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;
}));
}
}
我还想说,如果我使用SUBSCRIBE而不是PIPE,SwitchMap,令牌将被刷新,只有请求不会从头开始重复。
推荐答案
您的代码应该是:-
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).then((request)=> {
modifiedRequest = request.clone();
throw "replay";
});
}
}
}),retryWhen(errors => errors);
}
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 await authService.Signin(authmodel).pipe(
map(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 req;
}
}) , catchError(err => {
console.log(err);
return Observable;
})).toPromise();
}
}
原因:-Tap不订阅您正在返回的内心可察觉。Mergeap就是这么做的。应使用正确的运算符完成流合并。
这篇关于为什么SwitchMap在角度拦截器(角度9)中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文