Как исправить токен доступа обновления из первого http-запроса, который выдает ошибку GET 401 - PullRequest
0 голосов
/ 30 апреля 2019

Проблема в том, что, когда срок действия access token истек, и я делаю любой щелчок, токен доступа не обновляется. Но когда я делаю второй щелчок, он обновляется. За первый клик я получаю «GET 401 error». Реальная проблема для меня - получить токен доступа перед любым HTTP-запросом в interceptor.

Я попытался switchMap, чтобы мой код дождался токена доступа, но он не работал. У вас есть идеи, как я могу это исправить?

export class DevelopmentInterceptor implements HttpInterceptor {
    constructor(
        private authService: AuthService,
        private router: Router,
        private toastr: ToastrService,
        private translate: TranslateService
    ) { }

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const headers = new HttpHeaders({
        'Content-Type': 'application/json; charset=utf-8',
        'Authorization': `Bearer ${this.authService.getAccessToken()}`
    });
    let apiReq = null;
    if (req.url.indexOf('i18n') >= 0) {
        apiReq = req;
    } else if (req.url.indexOf('token') >= 0) {
        apiReq = req.clone({ url: environment.authServerUrl + `${req.url}` });
    } else if (req.url.indexOf('sign-up') >= 0) {
        apiReq = req.clone({ url: environment.signupUrl });
    } else if (req.url.indexOf('api/users') >= 0 || req.url.indexOf('api/roles') >= 0 || req.url.indexOf('api/permissions') >= 0) {
        apiReq = req.clone({ headers: headers, url: environment.authServerUrl + `${req.url}` });
    } else {
        apiReq = req.clone({ headers: headers, url: environment.backenUrl + `${req.url}` });
    }

    if (req.url.endsWith('token')) {
        return next.handle(apiReq).catch((err: any) => { //<--if error use a catch
            if (err instanceof HttpErrorResponse) {
                return this.handleError(err);
            }
        });
    } else {
        return this.authService.checkExpiry().switchMap( (result) => {
            if (result) {
                return next.handle(apiReq)
                    .catch((err: any) => { // <--if error use a catch
                        if (err instanceof HttpErrorResponse) {
                            return this.handleError(err);
                        }
                    });
            }
        } )
    }
}

private handleError(err: Response | any) {
        ...
    }
}

public checkExpiry() : Observable<any> {
    if (!this.cookieService.get('user_id')) {
        this.removeTokens();  // not logged in
        return Observable.of(true);
    } else if (!this.cookieService.check('access_token')) {
        if (this.cookieService.check('refresh_token')) {
            if (this.secondsTillExpiry('refresh_token') > 0) {
                return this.refreshAccessToken().switchMap((data:any) => {
                    if (data) {
                        this.saveTokenInCookies(data);
                        this.updateExpiration(data);
                        return Observable.of(true);
                    }
                })
            } else {
                this.router.navigate(['/login']);
                this.removeTokens();
                return Observable.of(true);
            }
        }
    } else if (this.cookieService.check('access_token') ) {
        return Observable.of(true);
    }
}



public secondsTillExpiry(tokenMode: string): any {
    if (tokenMode == 'access_token') {
        return  ((new Date(1970, 0, 
                 1).setSeconds(jwt_decode(this.getAccessToken()).exp)) - 
                 (Math.round(Date.now()) / 1000));
    } else  if (tokenMode == 'refresh_token') {
        return  ((new Date(1970, 0, 
                 1).setSeconds(jwt_decode(this.getRefreshToken()).exp)) - 
                 (Math.round(Date.now()) / 1000));
      }
    }

private refreshAccessToken(): Observable<Object> {
    const params = 'refresh_token=' + this.getRefreshToken() + 
'&grant_type=refresh_token';
    return this.http.post(this.authUrl, params, this.getOptions());

}

1 Ответ

0 голосов
/ 01 мая 2019

вы также можете проверить токен истечения срока действия перед отправкой любого запроса в CanActivate, и если он действителен, чтобы пользователь мог перейти на требуемый маршрут, иначе он будет перенаправлен на login Вот пример, чтобы справиться с этим

  canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
let accesstoken: string = next.queryParams.accesstoken;
if (this.authService.IsAuthenticated) {
  let user = this.authService.GetUser(); 
  let CurrentDate = new Date();
  let date = CurrentDate.getFullYear() + "-" + (CurrentDate.getMonth() + 1) + "-" + CurrentDate.getDate();
  if (user.expire_date) {
    if (Date.parse(date) <= Date.parse(user.expire_date)) {
      if (accesstoken) {
        // if token in url, redirect to url without token :)
        if (user.uuid == accesstoken)
          this.router.navigateByUrl(window.location.pathname);
        // if new token is not the same of current one, Register with new token
        else {
          return this.authService.checkAccess(accesstoken).pipe(
            map(data => {
              if (data === true) {
                if (accesstoken) {
                  this.router.navigateByUrl(window.location.pathname);
                }
                return true;
              } else {
                this.router.navigate(['/login']);
                return false;
              }

            })
          );
        }
      }
      return true;
    }
    else if (Date.parse(date) > Date.parse(user.expire_date)) {
      this.router.navigate(['/login']);
      return false;
    }
  }
}
else {
  this.router.navigate(['/login']);
  return false;
}

}

вы должны обработать его в соответствии с вашим кодом

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