angular-7-拦截器-重试-请求-令牌刷新后
angular-7-interceptor-retry-requests-after-token-refresh
我正在尝试为令牌过期的失败请求实施拦截器。我尝试了多种方法,但仍然没有成功。
我在下面参考了 URL 并阅读了多篇博客。每个人都建议切换地图方法但不与我合作。
Angular 4 Interceptor retry requests after token refresh
我已经尝试将所有请求收集到 cachedRequests: Array> = [];
但不知道如何使用它来重新触发失败的请求。
this.next.handle(request) 在成功刷新令牌后不召回。不过我可以看到更新后的请求对象。
有人可以指出在 angular 7 中参考的地方吗
"rxjs": "~6.3.3", "rxjs-compat": "^6.5.2", 实现拦截器。
下面是对我有用的代码,但只得到令牌的响应
``````````
handleError(request: HttpRequest<any>, next: HttpHandler, err) {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.service.getNewToken().pipe(filter(token => token != null),
take(1),
switchMap((token: any) => {
console.log('token', token);
if (token && token.access_token && token.refresh_token) {
sessionStorage.setItem('accessToken', token.access_token);
sessionStorage.setItem('refreshToken', token.refresh_token);
}
request = this.addHeader(request);
request.headers.getAll('Authorization');
return next.handle(request);
})).subscribe(results => this.subject.next(results));
}
}
}
`````````
更新 2:在尝试了多种方法后我发现
- returnnext.handle(请求); <-- 这根本就没有被调用
- return next.handle(请求).订阅(); <-- 这是被调用的
但不更新对请求组件的响应。
感谢指点
回复晚了。我就是这样做的。
也适用于并行请求。
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse, HttpEvent, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { GlobalService } from './global.service';
import { tap, mergeMap, switchMap, filter, take, flatMap, catchError } from 'rxjs/operators';
import { Observable, Subject, throwError, of, BehaviorSubject } from 'rxjs';
@Injectable()
export class InterceptorService implements HttpInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(public globalService: GlobalService) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = this.addHeader(request);
// console.log('request ', request);
return next.handle(request).pipe(catchError((error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
request = this.addHeader(request);
console.log('Token request');
return this.globalService.getRefershToken().pipe(
switchMap((token: any) => {
console.log('inside token');
this.isRefreshing = false;
if (token && token.access_token && token.refresh_token) {
sessionStorage.setItem('accessToken', token.access_token);
sessionStorage.setItem('refreshToken', token.refresh_token);
}
// request = this.addHeader(request);
// console.log('request: ', request);
this.refreshTokenSubject.next(token);
return next.handle(this.addHeader(request));
}));
} else {
console.log('inside else call');
console.log('token : ', this.refreshTokenSubject.getValue());
return this.refreshTokenSubject.pipe(
filter(token => (token != null && token != undefined)),
take(1),
switchMap(() => {
console.log('adding header in else');
return next.handle(this.addHeader(request))
}));
}
}
}
}));
}
private addHeader(request: HttpRequest<any>) {
let getEndPoint = request.url.split('/')[request.url.split('/').length - 1];
if (getEndPoint !== 'refreshToken') {
const accessToken = sessionStorage.getItem('accessToken');
request = request.clone({
setHeaders: {
Authorization: `Bearer ${accessToken}`
}
});
} else if (getEndPoint === 'refreshToken') {
const refreshToken = sessionStorage.getItem('refreshToken');
request = request.clone({
setHeaders: {
applicationCode: environment.applicationCode,
'refresh-token': `${refreshToken}`,
}
});
}
return request;
}
}
我正在尝试为令牌过期的失败请求实施拦截器。我尝试了多种方法,但仍然没有成功。
我在下面参考了 URL 并阅读了多篇博客。每个人都建议切换地图方法但不与我合作。 Angular 4 Interceptor retry requests after token refresh
我已经尝试将所有请求收集到 cachedRequests: Array> = []; 但不知道如何使用它来重新触发失败的请求。
this.next.handle(request) 在成功刷新令牌后不召回。不过我可以看到更新后的请求对象。
有人可以指出在 angular 7 中参考的地方吗
"rxjs": "~6.3.3", "rxjs-compat": "^6.5.2", 实现拦截器。
下面是对我有用的代码,但只得到令牌的响应
``````````
handleError(request: HttpRequest<any>, next: HttpHandler, err) {
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
this.service.getNewToken().pipe(filter(token => token != null),
take(1),
switchMap((token: any) => {
console.log('token', token);
if (token && token.access_token && token.refresh_token) {
sessionStorage.setItem('accessToken', token.access_token);
sessionStorage.setItem('refreshToken', token.refresh_token);
}
request = this.addHeader(request);
request.headers.getAll('Authorization');
return next.handle(request);
})).subscribe(results => this.subject.next(results));
}
}
}
`````````
更新 2:在尝试了多种方法后我发现
- returnnext.handle(请求); <-- 这根本就没有被调用
- return next.handle(请求).订阅(); <-- 这是被调用的 但不更新对请求组件的响应。
感谢指点
回复晚了。我就是这样做的。
也适用于并行请求。
import { HttpInterceptor, HttpRequest, HttpHandler, HttpErrorResponse, HttpEvent, HttpResponse } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { environment } from 'src/environments/environment';
import { GlobalService } from './global.service';
import { tap, mergeMap, switchMap, filter, take, flatMap, catchError } from 'rxjs/operators';
import { Observable, Subject, throwError, of, BehaviorSubject } from 'rxjs';
@Injectable()
export class InterceptorService implements HttpInterceptor {
private isRefreshing = false;
private refreshTokenSubject: BehaviorSubject<any> = new BehaviorSubject<any>(null);
constructor(public globalService: GlobalService) {
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
request = this.addHeader(request);
// console.log('request ', request);
return next.handle(request).pipe(catchError((error: any) => {
if (error instanceof HttpErrorResponse) {
if (error.status === 401) {
if (!this.isRefreshing) {
this.isRefreshing = true;
this.refreshTokenSubject.next(null);
request = this.addHeader(request);
console.log('Token request');
return this.globalService.getRefershToken().pipe(
switchMap((token: any) => {
console.log('inside token');
this.isRefreshing = false;
if (token && token.access_token && token.refresh_token) {
sessionStorage.setItem('accessToken', token.access_token);
sessionStorage.setItem('refreshToken', token.refresh_token);
}
// request = this.addHeader(request);
// console.log('request: ', request);
this.refreshTokenSubject.next(token);
return next.handle(this.addHeader(request));
}));
} else {
console.log('inside else call');
console.log('token : ', this.refreshTokenSubject.getValue());
return this.refreshTokenSubject.pipe(
filter(token => (token != null && token != undefined)),
take(1),
switchMap(() => {
console.log('adding header in else');
return next.handle(this.addHeader(request))
}));
}
}
}
}));
}
private addHeader(request: HttpRequest<any>) {
let getEndPoint = request.url.split('/')[request.url.split('/').length - 1];
if (getEndPoint !== 'refreshToken') {
const accessToken = sessionStorage.getItem('accessToken');
request = request.clone({
setHeaders: {
Authorization: `Bearer ${accessToken}`
}
});
} else if (getEndPoint === 'refreshToken') {
const refreshToken = sessionStorage.getItem('refreshToken');
request = request.clone({
setHeaders: {
applicationCode: environment.applicationCode,
'refresh-token': `${refreshToken}`,
}
});
}
return request;
}
}