Angular中canactivate方法中的API调用

时间:2018-11-17 15:11:54

标签: angular

我在Angular中使用canActivate使用guards。我想检查用户是否已通过身份验证,并根据结果保护路由。 用户有两种类型:Type1Type2,因此可以通过Type1Type2unauthenticated验证用户。 以下guard适用于Type1用户。

这是我的代码:

constructor(private authservice: AuthService, private router: Router, private route: ActivatedRoute){}
    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean{

        const self = this;
        const expectedType = "type1";

        this.authservice.isUserAuthenticatedbyType(expectedType).then(
            function(data){
                if(data === false){
                    console.log(data);
                    self.router.navigate(['/'], {relativeTo: self.route});
                }
                return data;
            },
            function(error){
                self.router.navigate(['/']);
                return false;
            }
        );
        return false;
    }

问题是我进行API调用以验证用户是否已通过身份验证,并且在从API返回结果之前执行return false;。因此,我暂时看到一个不同的页面,然后将其路由到正确的页面。如何解决此问题,我不想在API调用之前返回false或true,但是不这样做会产生错误。

我还尝试了以下方法:

return this.authservice.isUserAuthenticatedbyType(expectedType)

但是对于http://localhost:4200用户,这只是将我导航到unauthenticated网址。

我有以下路线:

{ path: "", component: HomeComponent },

因此,在上述情况下,应该已调用HomeComponent,但是没有调用HomeComponent的ngOnInit

3 个答案:

答案 0 :(得分:2)

如果您使用的是promise,请尝试类似的操作-主要想法是保持路由,直到您完成Api的呼叫-我遇到了同样的问题,我通过返回{{1 }}在我的Promise<boolean>

route

此方法解决了我的问题-等待 API 返回数据并为路线指明方向

希望它能正常工作-编码愉快!!

答案 1 :(得分:1)

您可以这样实现:

角度<= 7.0.0

public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  return this.authservice.isUserAuthenticatedbyType("type1").pipe(
    map(data => {
      if (data === false) {
        this.router.navigate(['/']);
        return false;
      }

      return !!data;
    }),
    catchError(() => {
      this.router.navigate(['/']);
      return of(false);
    }),
  );
}

角度> = 7.1.0

从Angular 7.1.0开始(请注意,它在7.0.x中不是 ),也可以改为执行此操作,如果您有多个防护,它会更短且更可预测:

public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
  return this.authservice.isUserAuthenticatedbyType("type1").pipe(
    map(data => data === false ? this.router.parseUrl("/") : !!data)
    catchError(() => this.router.parseUrl("/")),
  );
}

答案 2 :(得分:1)

您也可以这样尝试:

canActivate(): Observable<boolean> | Promise<boolean> | boolean {
    return new Promise(res => {
        this.authservice.isUserAuthenticatedbyType("type1").subscribe(
            (data) => {
                if (data === true) {
                    res(true);
                } else {
                    this.router.navigate(['/']);
                    res(false);
                }
            },
            (error) => {
                this.router.navigate(['/']);
                res(false);
            }
        );
    });
}