簡體   English   中英

如何修復第一個http請求中的刷新訪問令牌,這會產生GET 401錯誤

[英]How to fix refresh access token from the first http request which gives GET 401 error

問題是,當access token過期並且我進行任何點擊時,訪問令牌不會刷新。 但是當我第二次點擊時,它會刷新。 第一次點擊,我得到' GET 401 error '。 對我來說,實際問題是在interceptor中的任何HTTP請求之前獲取訪問令牌。

我為我的代碼嘗試使用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());

}

你也可以在發送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;
}

}

你應該根據你的代碼處理它

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM