如果令牌过期时为活动的auth-guard,则不会刷新

问题描述

如果用户未通过身份验证,我激活了auth-guard来阻止路由,则1小时后令牌显然已过期,但未调用刷新令牌。

如果我删除了auth-guard,则刷新令牌将被正确调用

还请注意,在激活了auth-guard的情况下,当令牌过期并且我进行新的调用时会返回401未经授权的错误,如果我执行F5并刷新页面,则将调用refreh-token,这将使我继续去上班。但是我希望在不强制刷新页面的情况下才能正常工作。

我在下面留给我我的代码

app.component.ts

import {Component,Injector,OnInit} from '@angular/core';
import {Router,NavigationEnd} from '@angular/router';
import {LoginService} from './login/login.service';
import {RestService} from './shared/rest.service';
import {Restangular,RestangularHttp} from 'ngx-restangular';
import {Costants} from './Enum/costants.enum';
import 'rxjs/add/operator/switchMap';
import {HttpHeaders} from '@angular/common/http';

@Component({
  // tslint:disable-next-line
  selector: 'body',template: '<router-outlet></router-outlet>'
})
export class AppComponent implements OnInit {
  constructor(private loginService: LoginService,private restService: RestService,private http: RestangularHttp,private injector: Injector,private router: Router) {
    const authRestangular = new Restangular(
      {},this.injector,this.http
    ).withConfig(restangularConfigurer => {
      restangularConfigurer.setBaseUrl(Costants.BASE_URL);
      restangularConfigurer.setRequestSuffix(Costants.REQUEST_SUFFIX);
      restangularConfigurer.setRequestInterceptor(function (elem,operation) {
        if (operation === 'remove') {
          return undefined;
        }
        return elem;
      });

      const authToken = loginService.getToken();
      
      if (null !== authToken) {
        restangularConfigurer.setDefaultHeaders({'Authorization': 'Bearer ' + authToken});
      } else {
        router.navigate(['login']);
      }

      const refreshAccesstoken = function () {
        const refreshPayload = {
          refresh_token: loginService.getRefreshToken()
        };

        return restService.create({service: Costants.REST_REFRESH_TOKEN,model: refreshPayload});
      };

      restangularConfigurer.addErrorInterceptor((response,subject,responseHandler) => {
        if (response.status === 403 || response.status === 401) {
          refreshAccesstoken()
            .switchMap(refreshAccesstokenResponse => {
              restangularConfigurer.setDefaultHeaders({'Authorization': 'Bearer ' + refreshAccesstokenResponse.token});
              const newHeaders = new HttpHeaders().set('Authorization','Bearer ' + refreshAccesstokenResponse.token);
              let newReq = response.request.clone({headers: newHeaders});
              return response.repeatRequest(newReq);
            })
            .subscribe(
              res => responseHandler(res),err => subject.error(err)
            );

          return false;
        }
        return true; // error not handled
      });
    });

    restService.authRestangular = authRestangular;
  }

  ngOnInit() {
    this.router.events.subscribe((evt) => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      window.scrollTo(0,0);
    });
  }
}

auth-guard.service.ts

import { Injectable } from '@angular/core';
import { Router,CanActivate } from '@angular/router';
import {LoginService} from '../login/login.service';

@Injectable()
export class AuthGuardService implements CanActivate {
  constructor(public loginService: LoginService,public router: Router) {}
  canActivate(): boolean {
    if (!this.loginService.getToken()) {
      this.router.navigate(['login']);
      return false;
    }
    return true;
  }
}

login.service.ts

import { Injectable } from '@angular/core';
import { AsyncLocalStorage } from 'angular-async-local-storage';
import { RestService } from '../shared/rest.service';
import { Costants } from '../Enum/costants.enum';

@Injectable()
export class LoginService {
  private _token: string = null;
  private _refreshToken: string = null;

  constructor(protected localStorage: AsyncLocalStorage,private restService: RestService) {
  }

  public getRefreshToken() {
    return localStorage.getItem(Costants.LOCALSTORAGE_APP_PREFIX + 'refreshToken');
  }

  public setRefreshToken(value: string) {
    localStorage.setItem(Costants.LOCALSTORAGE_APP_PREFIX + 'refreshToken',value);
  }

  public getToken() {
    return localStorage.getItem(Costants.LOCALSTORAGE_APP_PREFIX + 'token');
  }

  public setToken(value: string) {
    localStorage.setItem(Costants.LOCALSTORAGE_APP_PREFIX + 'token',value);
  }
}

问题可能出在控件的 auth-guard 内部

if(!this.loginService.getToken()){

因为令牌可能存在但已经过期,我认为稍后再返回true,它将给出未经授权的401错误,然后在 app.component.ts 中进行经典浏览 ...,但不会输入 app.component.ts (我已通过日志验证)

如果这是问题所在,您如何建议更新 auth-guard.service ,以便在401错误之后调用refreshToken?

谢谢,如果您需要其他代码,请询问。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)