执行异步函数的Angular2 authguards失败

时间:2017-06-22 10:52:25

标签: angular typescript

我想通过检查用户是否从服务器登录但是异步功能没有被执行来保护我的路由

这是我的代码:

canActivate (route: ActivatedRouteSnapshot , state: RouterStateSnapshot): Observable<any> {
  let permission = route.data[ "permission" ]; //permissions are set on the routes
   if(permission){
       ..execute another function which works
    )
  }else{
    return this.checkLogin()  //this one is the one that fails
  }
}

在函数checkLogin上:

checkLogin (url?: string): any {
  this.authService.checkLoggedin()
    .subscribe(
      res=>{
       if(res){
         return true;
       }else{
          this.router.navigate ( [ '/login' ] );
          return false
       }

    }
  )
}

现在进行身份验证服务

checkLoggedin():Observable<any> {
//check from server if user is loggdin
  return this._httpclient.get(this.authurl + "/default/is-loggedin")
    .map(res => {

        return res.json().data;
    },error=>{
      return Observable.of(false);
      }
    );
}

我哪里可能出错?

3 个答案:

答案 0 :(得分:3)

checkLogin必须返回Observable<boolean>Promise<boolean>(如果是同步的话,则返回普通boolean)。你没有退货。

试试这个。而不是subscribe只需使用map来修改checkLoggedin()发出的值,然后使用适当的布尔值返回Observable

checkLogin (url?: string): Observable<boolean> {
    return this.authService.checkLoggedin()
    .map(
      res=>{
       if(res){
         return true;
       }else{
          this.router.navigate ( [ '/login' ] );
          return false
       }
    });
}

一个好的提示也可能是永远不要将函数声明为返回any,始终将其声明为您要返回的实际类型,然后编译器可以完成其工作并告诉您是否忘记返回结果当你真的需要归还一个时。

同样checkLoggedin():Observable<any>应为checkLoggedin():Observable<boolean>以最大限度地发现错误(并且您可能必须对json数据进行一些转换,然后才能使其正常工作)。

答案 1 :(得分:0)

this.router.navigate()在导航成功时解析为true,因此您实际上返回true。

https://angular.io/api/router/Router

在调用checklogin并根据其结果后,你应该在canActivate方法的else块中实际执行router.navigate。

答案 2 :(得分:0)

尝试这种方式:

 public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
        let permission = route.data[ "permission" ]; //permissions are set on the routes
       return !permission ? true : this.checkLoggedin()
                    .map((res: any) => {
                        if (res) {
                            return true;
                        }

                        throw new Error('Not logged in!');
                    })
                    .catch(() => {
                        this.router.navigate(['/login']);
                        return Observable.of(false);
                    });
            }