【问题标题】:AuthGuard can activate goes to end of function and returns false instead of waiting for subscription to return trueAuthGuard 可以激活到函数结束并返回 false 而不是等待订阅返回 true
【发布时间】:2017-10-26 00:10:24
【问题描述】:

我正在制作一个 Angular 4 网络应用程序。我需要保护我的路线,所以我使用AuthGuardCanActivate 来检查用户是否可以访问某个路线。

CanActivate 首先检查id 是否在sessionStorage 中,否则如果用户被授权,它会检查我的后端。如果我在sessionStorage 中单击带有id 的项目并进入checkIfIDInStorage 它工作正常,但是如果它进入else 并调用我的API,它将进入函数的末尾并在调用返回 true 之前返回 false 如果我删除了 canActivate 中的 return false,它仍然不起作用。如果我在看到它返回 true 后再次单击该项目,它就可以正常工作。

控制台输出

can activate else
before return false
in subscribe if
true
in store

Guard.ts

canActivate (route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
  const id = route.params.id;
  if (this.checkIfIDInStorage(id)) {
    console.log("checking id");
    return true;
  }
  else {
    console.log("in can activate else");
    this.API.checkProjectOwnership(id).subscribe((data) =>
    {
      console.log("in subscribe if");
      if (data.type === 'AL') {
        console.log("true");
        this.storeProjectID(id);
        return true;
      }
      else  {
        console.log("in subscribe else ");
        this.router.navigate(['/dashboard']);
      }
    });
  }
  console.log("before return false");
  return false;
}

storeProjectID(id: string) {
  console.log("in store");
  this.session.store('id', id);
  return true;
}

getProjectID() {
  return this.session.retrieve('id');
}

checkIfIDInStorage(id: string) {
  const storedID = this.getProjectID();
  return (id ===  storedID);
}

API.service.ts

  checkProjectOwnership(params: URLSearchParams): Observable<any> {
    const URL = `${this.API}/projects/ownership?id=${params}`;
    return this.auth.refreshToken()
      .flatMap(() => this.authHttp.get(URL, this.headers))
      .map((response: Response) => response.json())
      .share()
      .catch(this.handleError);
  }

【问题讨论】:

  • 这是因为 API 调用是异步的。该函数不会等待异步调用完成。您可以尝试使用路由解析器。它等待您的异步 API 调用。或者你可以让你的守卫返回一个 Observable 而不是 Boolean,如下所示:stackoverflow.com/questions/38425461/…

标签: angular


【解决方案1】:

我能够通过返回一个 observable 来解决它。

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean
{
  const id = route.params.id;
  return new Observable<boolean>((observer) =>
  {
    if (this.checkIfIDInStorage(id)) {
      observer.next(true);
      observer.complete();
    }
    else {
      const params = new URLSearchParams();
      params.append('id', id);
        this.API.checkProjectOwnership(id).subscribe((data) =>
        {
          console.log("in subscribe if");
          if (data.type === 'AL') {
            this.storeProjectID(id);
            observer.next(true);
            observer.complete();
          }
          else {
            this.router.navigate(['/dashboard']);
            observer.next(false);
            observer.complete();
            return false;
          }
        });
    }
  });
}

【讨论】:

    【解决方案2】:
    @Injectable()
    export class DrawingBoardGuard implements CanActivate {
    
      constructor( private _http: HttpClient, private _router : Router) {
    
      }
    
      canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
          let url : string = 'someUrl';
          return new Observable<boolean>((observer:any) => {
            this._http.get(url)
              .map((result) => {
                if(!result.isPermitted){
                  this.navigateToOtherPage(...);
                  observer.next(false);
                  observer.complete();
                  return false;
                }else {
                  observer.next(true);
                  observer.complete();
                  return true;
                }
              })
              .catch(err => {
                this.navigateToOtherPage(...);
                return Observable.of(false);
              });
          });
    
      }
    

    【讨论】:

      猜你喜欢
      • 2023-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-25
      • 2016-03-23
      • 2014-04-24
      相关资源
      最近更新 更多