我已经使用Angular在一个离子应用程序的http拦截器中实现了一个刷新令牌过程,我想我错过了一些让代码正常工作的东西:
refreshTokens令牌函数:
async refreshTokens() {
return new Promise((resolve, reject) => {
this.dataService
.post(this.apiUriService.refreshTokenUri(), {
refresh_token: this.authData.refreshToken,
})
.pipe(take(1))
.subscribe({
next: (res: any) => {
if (!res) {
return reject(null);
}
const resData = res.data ? res.data : null;
this.utils.setItemOnLocalStorage(
Constants.authDataStorageItemName,
resData
);
resolve(resData);
},
error: (error) => {
return reject(error);
},
});
});
}
字符串
和错误401错误功能:
async handle401Error(req: HttpRequest<any>, next: HttpHandler, error: any) {
return from(this.refreshTokens()).pipe(
switchMap((res: any) => {
console.log('switchMap fired!');
const request = this.addToken(req, res.access_token);
return next.handle(request);
}),
catchError((error) => {
this.logoutUser();
return throwError(error);
})
);
}
型
下面是完整的拦截器类代码:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import {
HttpRequest,
HttpResponse,
HttpHandler,
HttpEvent,
HttpInterceptor,
HttpErrorResponse,
} from '@angular/common/http';
import {
Observable,
throwError,
BehaviorSubject,
tap,
take,
from,
switchMap,
catchError,
} from 'rxjs';
import { AuthService } from './auth/auth.service';
import { ApiUriService } from './api-uri.service';
import { DataService } from './data.service';
import { Constants } from '../constants/constants';
import { CommonUtilsService } from './common-utils.service';
import { UserService } from './user/user.service';
@Injectable()
export class CommonHttpInterceptor implements HttpInterceptor {
tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>('');
get authData() {
return this.authService.readUserInfoFromLocalStorage();
}
constructor(
private authService: AuthService,
private router: Router,
private apiUriService: ApiUriService,
private dataService: DataService,
private userService: UserService,
private utils: CommonUtilsService
) {}
intercept(
request: HttpRequest<unknown>,
next: HttpHandler
): Observable<HttpEvent<unknown>> {
const userInfoData = this.authService.authUserData;
const headers: any = {};
if (userInfoData && userInfoData.accessToken) {
headers['Authorization'] = `Bearer ${userInfoData.accessToken}`;
}
const clonedRequest = request.clone({ setHeaders: headers });
return next.handle(clonedRequest).pipe(
tap(
(event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
// case when we need to transform the response
}
},
(error: HttpErrorResponse) => {
// handle refresh token in case of the access token is expired
if (error.status === 401) {
return this.handle401Error(request, next);
}
return throwError(error);
}
)
);
}
logoutUser() {
this.authService.doLogout();
this.router.navigate(['auth/login']);
}
handle401Error(req: HttpRequest<any>, next: HttpHandler) {
return from(this.refreshTokens()).pipe(
switchMap((res: any) => {
console.log('switchMap fired!');
const request = this.addToken(req, res.access_token);
return next.handle(request);
}),
catchError((error) => {
this.logoutUser();
return throwError(error);
})
);
}
// refresh access token OR logout user if request failed
refreshTokens() {
return new Promise((resolve, reject) => {
this.dataService
.post(this.apiUriService.refreshTokenUri(), {
refresh_token: this.authData.refreshToken,
})
.pipe(take(1))
.subscribe({
next: (res: any) => {
if (!res) {
return reject(null);
}
const resData = res.data ? res.data : null;
this.utils.setItemOnLocalStorage(
Constants.authDataStorageItemName,
resData
);
resolve(resData);
},
error: (error) => {
return reject(error);
},
});
});
}
//add token to authorization header
private addToken(request: HttpRequest<any>, token: any) {
const newToken = this.authService.shiftoCookieValue
? this.authService.shiftoCookieValue
: token;
if (newToken) {
let clone: HttpRequest<any>;
clone = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`,
},
});
return clone;
}
return request;
}
}
型
我的问题是switchMap没有被触发,也没有在控制台中记录任何日志。所以没有发送下一个请求。
1条答案
按热度按时间j5fpnvbx1#
问题是,您的错误处理程序方法在
tap()
内部被调用,结果Observable被返回。但在tap()
中,返回值被忽略,因此Observable不会被订阅。你可以使用catchError,返回的Observable将被订阅。
字符串