首页 > 解决方案 > Angular中canactivate方法中的API调用

问题描述

我在 Angular中canActivate使用。guards我想检查用户是否经过身份验证并根据结果保护路由。有两种类型的用户:Type1和,Type2因此用户可以使用 或 进行身份验证。以下内容供用户使用。Type1Type2unauthenticatedguardType1

这是我的代码:

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 调用以验证用户是否已通过身份验证并return false;在 API 结果之前执行。所以,暂时我看到一个不同的页面,然后它被路由到正确的页面。我该如何解决这个问题,我不想在 API 调用之前返回 false 或 true,但不这样做会产生错误。

我还尝试了以下方法:

return this.authservice.isUserAuthenticatedbyType(expectedType)

但这只是在用户http://localhost:4200的情况下将我导航到 url unauthenticated

我有以下路线:

{ path: "", component: HomeComponent },

所以,在上面的场景中,HomeComponent应该已经调用了,但是ngOnInitHomeComponent 没有被调用。

标签: angular

解决方案


你可以像这样实现它:

角度 <= 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("/")),
  );
}

推荐阅读