Проблема с созданием токена refre sh через HttpInterceptor - PullRequest
0 голосов
/ 23 января 2020

Я пытаюсь внедрить токены refre sh в нашем приложении, используя следующий учебник:

https://codinglatte.com/posts/angular/refreshing-authorization-tokens-angular-6/

Я получаю следующую ошибку:

TypeError: Cannot read property 'pipe' of null
    at HttpAuthInterceptor.push../src/app/Interceptors/newauth.interceptor.ts.HttpAuthInterceptor.intercept (newauth.interceptor.ts:38)
    at HttpInterceptorHandler.handle (http.js:1279)
    at LoaderInterceptor.intercept (loader.interceptor.ts:55)
    at HttpInterceptorHandler.handle (http.js:1279)
    at HttpXsrfInterceptor.intercept (http.js:1888)
    at HttpInterceptorHandler.handle (http.js:1279)
    at HttpInterceptingHandler.handle (http.js:1932)
    at MergeMapSubscriber.project (http.js:1099)
    at MergeMapSubscriber._tryNext (mergeMap.js:61)
    at MergeMapSubscriber._next (mergeMap.js:51)

Мой код:

import { HttpEvent,HttpHandler,HttpInterceptor,HttpRequest } from '@angular/common/http';
import { Injectable, Injector } from '@angular/core';
import { Router } from '@angular/router';
import { Observable, throwError } from 'rxjs';
import { catchError, switchMap } from 'rxjs/operators';
import { AuthService } from '../Services/Auth.service';


@Injectable()
export class HttpAuthInterceptor implements HttpInterceptor {

  constructor(private injector: Injector, private Route: Router) { }

  inflightAuthRequest = null;

  intercept(
    req: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    // exempt some paths from authentication
    if (req.headers.get('authExempt') === 'true') {
      return next.handle(req);
    }

    const authService = this.injector.get(AuthService);

    if (!this.inflightAuthRequest) {
      this.inflightAuthRequest = authService.getToken();
    }

    return this.inflightAuthRequest.pipe(
      switchMap((newToken: string) => {
        // unset request inflight
        this.inflightAuthRequest = null;

        // use the newly returned token
        const authReq = req.clone({
          headers: req.headers.set('token', newToken ? newToken : '')
        });

        // resend the request
        return next.handle(authReq);
      }),
      catchError(error => {
        if (error.status === 401) {
          // check if the response is from the token refresh end point
          const isFromRefreshTokenEndpoint = !!error.headers.get('unableToRefreshToken');

          if (isFromRefreshTokenEndpoint) {
            localStorage.clear();
            this.Route.navigate(['/login']);
            return throwError(error);
          }

          if (!this.inflightAuthRequest) {
            this.inflightAuthRequest = authService.refreshToken();

            if (!this.inflightAuthRequest) {
              // remove existing tokens
              localStorage.clear();
              this.Route.navigate(['/login']);
              return throwError(error);
            }
          }

          return this.inflightAuthRequest.pipe(
            switchMap((newToken: string) => {
              // unset inflight request
              this.inflightAuthRequest = null;

              // clone the original request
              const authReqRepeat = req.clone({
                headers: req.headers.set('token', newToken)
              });

              // resend the request
              return next.handle(authReqRepeat);
            })
          );
        } else {
          return throwError(error);
        }
      })
    );
  }
}

Может кто-нибудь сказать мне, что я делаю неправильно? Строка 38 в ошибке ссылается на return this.inflightAuthRequest.pipe(. Я не уверен, что мне нужно делать, и буду очень признателен за помощь.

1 Ответ

0 голосов
/ 23 января 2020

Вам не хватает этой части:

if (!this.inflightAuthRequest) {
  this.inflightAuthRequest = authService.getToken();
}

После:

const authService = this.injector.get(AuthService);

Должно быть, я забыл включить эту часть в статью, хотя был в репо. Извините за это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...