Angular 返回可观察到的内部可观察到的角度4的可激活保护

Angular 返回可观察到的内部可观察到的角度4的可激活保护,angular,typescript,angular-ui-router,observable,Angular,Typescript,Angular Ui Router,Observable,因此,我必须在路由器的CANActive守卫中做两件事。首先,我必须检查用户是否被授权,我通过调用openidcsecurity服务来实现这一点,然后,如果用户被授权,我必须通过调用另一个返回UserProfile(包括其角色)的服务来检查用户角色。我知道我可以返回一个可观察的,事实上,如果我这样做: return this.oidcSecurityService.getIsAuthorized(); 它可以工作,但显然我没有检查用户角色。现在我有这个: canActivate(route:

因此,我必须在路由器的CANActive守卫中做两件事。首先,我必须检查用户是否被授权,我通过调用openidcsecurity服务来实现这一点,然后,如果用户被授权,我必须通过调用另一个返回UserProfile(包括其角色)的服务来检查用户角色。我知道我可以返回一个可观察的,事实上,如果我这样做:

return this.oidcSecurityService.getIsAuthorized();
它可以工作,但显然我没有检查用户角色。现在我有这个:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

return this.oidcSecurityService.getIsAuthorized()
  .map(
    data => {
      if (data === false) {
        this.router.navigate(['/login']);
        return data;
      }
      if (data === true) {
        const roles = route.data['roles'] as Array<string>;
        if (roles) {
        this.profileService.getObservableUserProfileFromServer().map(userProfile => {
          const userRoles = userProfile.Roles;
          for (const role of roles) {
            if (userRoles.indexOf(role) > -1) {
              return true;
            }
          }
          return false;
        });
        }
        return data;
      }
    },
    error => {
      this.router.navigate(['/login']);
      return error;
    }
  );
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot){
返回此.oidcSecurityService.getIsAuthorized()
.地图(
数据=>{
如果(数据===false){
this.router.navigate(['/login']);
返回数据;
}
如果(数据===真){
const roles=route.data['roles']作为数组;
if(角色){
this.profileService.getObservableUserProfileFromServer().map(userProfile=>{
const userRoles=userProfile.Roles;
for(角色的常量角色){
if(userRoles.indexOf(role)>-1){
返回true;
}
}
返回false;
});
}
返回数据;
}
},
错误=>{
this.router.navigate(['/login']);
返回误差;
}
);
此.profileService.getObservableUserProfileFromServer()从未被调用,并且我不知道在知道用户已被授权后如何检查用户角色。我如何才能做到这一点?我可以在observable中返回observable吗

EDIT1:我将代码更改为:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {

return this.oidcSecurityService.getIsAuthorized()
  .map(
    data => {
      if (data === false) {
        this.router.navigate(['/login']);
        return data;
      }
      if (data === true) {
        const roles = route.data['roles'] as Array<string>;
        if (roles) {
          return this.profileService.getObservableUserProfileFromServer().toPromise().then(userProfile => {
              const userRoles = userProfile.Roles;
              for (const role of roles) {
                if (userRoles.indexOf(role) > -1) {
                  return true;
                }
              }
              return false;
          }
            );
        }
        return data;
      }
    },
    error => {
      this.router.navigate(['/login']);
      return error;
    }
  );
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot){
返回此.oidcSecurityService.getIsAuthorized()
.地图(
数据=>{
如果(数据===false){
this.router.navigate(['/login']);
返回数据;
}
如果(数据===真){
const roles=route.data['roles']作为数组;
if(角色){
返回此.profileService.getObservableUserProfileFromServer().toPromise()。然后(userProfile=>{
const userRoles=userProfile.Roles;
for(角色的常量角色){
if(userRoles.indexOf(role)>-1){
返回true;
}
}
返回false;
}
);
}
返回数据;
}
},
错误=>{
this.router.navigate(['/login']);
返回误差;
}
);
//返回此.oidcSecurityService.getIsAuthorized()

}

现在我可以看到如何调用this.profileService.getObservableUserProfileFromServer并从服务器接收结果,但结果没有在canActivate guard中计算,它只是忽略结果,并表示导航已取消

编辑最终版本:

@llai给了我答案,必须使用两个开关图来链接多个可观察对象,这里的最终代码是:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {

return this.oidcSecurityService.getIsAuthorized()
  .switchMap(
    data => {
      if (data === false) {
        this.router.navigate(['/login']);
        return Observable.of(false); // user not logged in, canActivate = false
      } else if (data === true) {
        const roles = route.data['roles'] as Array<string>;
        if (roles) {
          // return inner observable
          return this.profileService.getObservableUserProfileFromServer()
            .switchMap(userProfile => {
              const userRoles = userProfile.Roles;
              for (const role of roles) {
                if (userRoles.indexOf(role) > -1) {
                  // role found, canActivate = true
                  return Observable.of(true);
                }
              }
              // no matching role, canActivate = false
              return Observable.of(false);
            });
        } else {
          // no roles defined in route data, canActivate = false
          return Observable.of(true);
        }
      }
    });
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察{
返回此.oidcSecurityService.getIsAuthorized()
.开关图(
数据=>{
如果(数据===false){
this.router.navigate(['/login']);
返回Observable.of(false);//用户未登录,canActivate=false
}else if(数据===true){
const roles=route.data['roles']作为数组;
if(角色){
//返回内可观测
返回此.profileService.getObservableUserProfileFromServer()
.switchMap(userProfile=>{
const userRoles=userProfile.Roles;
for(角色的常量角色){
if(userRoles.indexOf(role)>-1){
//找到角色,canActivate=true
可观察的返回(真);
}
}
//没有匹配的角色,canActivate=false
可观察到的返回(错误);
});
}否则{
//路由数据中未定义角色,canActivate=false
可观察的返回(真);
}
}
});

}

正如Christian在评论中提到的,您应该使用
开关映射
将您的观测值链接在一起

在您的第一个实现中,您没有返回您的内部可观察对象,因此路由器从未订阅它,因此它从未被调用

在您的第二个实现中,您正在“订阅”(转换为promise+then)映射函数中的可观察对象,这使得内部可观察对象着火。但是,由于可观察对象没有返回到守卫,守卫没有等待内部可观察对象完成


相反,你应该链接观察对象并将链接序列返回给守卫。这将允许守卫订阅序列并等待正确的响应

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {

    return this.oidcSecurityService.getIsAuthorized()
      .switchMap(
        data => {
          if (data === false) {
            this.router.navigate(['/login']);
            return Observable.of(false); // user not logged in, canActivate = false
          }else if (data === true) {
            const roles = route.data['roles'] as Array<string>;
            if (roles) {
              // return inner observable
              return this.profileService.getObservableUserProfileFromServer()
                .map(userProfile => {
                  const userRoles = userProfile.Roles;
                  for (const role of roles) {
                    if (userRoles.indexOf(role) > -1) {
                      // role found, canActivate = true
                      return true;
                    }
                  }
                  // no matching role, canActivate = false
                  return false;
                });
            }else{
              // no roles defined in route data, canActivate = false
              return Observable.of(false)
            }
          }
        }
      }
    );

}
canActivate(路由:ActivatedRouteSnapshot,状态:RouterStateSnashot):可观察{
返回此.oidcSecurityService.getIsAuthorized()
.开关图(
数据=>{
如果(数据===false){
this.router.navigate(['/login']);
返回Observable.of(false);//用户未登录,canActivate=false
}else if(数据===true){
const roles=route.data['roles']作为数组;
if(角色){
//返回内可观测
返回此.profileService.getObservableUserProfileFromServer()
.map(userProfile=>{
const userRoles=userProfile.Roles;
for(角色的常量角色){
if(userRoles.indexOf(role)>-1){
//找到角色,canActivate=true
返回true;
}
}
//没有匹配的角色,canActivate=false
返回false;
});
}否则{
//路由数据中未定义角色,canActivate=false
可观察到的返回(错误)
}
}
}
}
);
}