Я пытаюсь реализовать функцию обновления токена в моем приложении angular 6. По этому вопросу есть много учебных пособий, и я следую учебным пособиям http://ericsmasal.com/2018/07/02/angular-6-with-jwt-and-refresh-tokens-and-a-little-rxjs-6/ и https://www.intertech.com/Blog/angular-4-tutorial-handling-refresh-token-with-new-httpinterceptor/.Оба в основном имеют одну и ту же идею.но я чувствую, что проблема, с которой я сталкиваюсь, связана с нашей текущей структурой вызова функции обновления токена.Ниже приведено объяснение
1) AuthInterceptor
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(private authService: AuthenticationService) { }
isRefreshingToken: boolean = false;
tokenSubject: BehaviorSubject<string> = new BehaviorSubject<string>(null);
intercept(request: HttpRequest<any>, next: HttpHandler) : Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any> | any> {
return next.handle(this.addTokenToRequest(request, this.authService.getAuthToken()))
.pipe(
catchError(err => {
if (err instanceof HttpErrorResponse) {
switch ((<HttpErrorResponse>err).status) {
case 401:
return this.handle401Error(request, next);
case 400:
return <any>this.authService.logout();
}
} else {
return throwError(err);
}
}));
}
private addTokenToRequest(request: HttpRequest<any>, token: string) : HttpRequest<any> {
return request.clone({ setHeaders: { Authorization: `Bearer ${token}`}});
}
private handle401Error(request: HttpRequest<any>, next: HttpHandler) {
if(!this.isRefreshingToken) {
this.isRefreshingToken = true;
// Reset here so that the following requests wait until the token
// comes back from the refreshToken call.
this.tokenSubject.next(null);
return this.authService.refreshToken()
.pipe(
switchMap((user) => {
if(user) {
this.tokenSubject.next(user.accessToken);;
localStorage.setItem('currentUser', JSON.stringify(user));
return next.handle(this.addTokenToRequest(request, user.accessToken));
}
return <any>this.authService.logout();
}),
catchError(err => {
return <any>this.authService.logout();
}),
finalize(() => {
this.isRefreshingToken = false;
})
);
} else {
this.isRefreshingToken = false;
return this.tokenSubject
.pipe(filter(token => token != null),
take(1),
switchMap(token => {
return next.handle(this.addTokenToRequest(request, token));
}));
}
}
}
2) AuthService
НашСервис токенов обновления вызывается по следующему правилу:
- . Для вызова маркера обновления мы отправляем запрос с заголовком Basic и значением btoa (someid + someotherid)
Наблюдения
- Он вызывает метод refreshtoken в сервисе auth, но затем снова из authinterceptor переходит в блок else и вызывает addTokenToRequest ().Таким образом, вместо добавления заголовка в качестве основного, он добавляет Bearer и снова отправляет ошибку 401.
Приведенный выше код использует localalstorage, мы используем файлы cookie.EG - this.cookieService.get ('access_token'), this.cookieService.set ('refresh_token', 'ddsdhsdhsdhsdhs')
Вкратце, мой метод refreshtoken должен сначала вызвать API с Basic изатем, когда полученный токен должен вызвать другие API с Bearer, к которому добавлен новый токен.
Пожалуйста, помогите мне в этом, так как я застрял на пару дней.Спасибо