简体   繁体   English

AuthGuard 可以激活到函数结束并返回 false 而不是等待订阅返回 true

[英]AuthGuard can activate goes to end of function and returns false instead of waiting for subscription to return true

I am making an Angular 4 web app.我正在制作一个 Angular 4 网络应用程序。 I need to protect my routes so I am using AuthGuard and CanActivate to check if the user can access a certain route.我需要保护我的路由,所以我使用AuthGuardCanActivate来检查用户是否可以访问某个路由。

CanActivate first checks if the id is in sessionStorage else it checks my backend if the user is authorized. CanActivate首先检查id是否在sessionStorage否则它会检查我的后端是否用户被授权。 If I click on a project with an id already in sessionStorage and it goes into the checkIfIDInStorage it works fine, however if it goes into the else and makes a call to my API it goes to the end of the function and returns false before the call returns true If I remove the return false in canActivate it still doesn't work.如果我在sessionStorage单击一个带有id的项目,它会进入checkIfIDInStorage它工作正常,但是如果它进入 else 并调用我的 API,它会转到函数的末尾并在调用之前返回 false返回 true 如果我在canActivate删除return false它仍然不起作用。 If I click on the project again after I see that it has returned true it works fine.如果我在看到它返回 true 后再次单击该项目,它可以正常工作。

Console output控制台输出

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

Guard.ts 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 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);
  }

I was able to solve it by returning an observable.我能够通过返回一个 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;
          }
        });
    }
  });
}
@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);
          });
      });

  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM