角度异步路由器防护

时间:2018-03-06 12:35:07

标签: angular

我们有一个Router Guard,用于检查用户是否已登录和管理员 它还应检查我们发送给服务器的请求是否具有正确的结果。

问题是canActivate函数在服务器请求完成之前完成,因此Router Guard始终为false。

我希望你有解决这个问题的方法

 canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    var user = JSON.parse(localStorage.getItem('currentUser'));
    if (user != null&&!user.isNotAdmin) {
      if(this.userService.isLoggedIn(user)){
          return true;
      }else{
          return false;
      }
    }else{

    // not logged in so redirect to login page with the return url
    this.router.navigate([''], { queryParams: { returnUrl: state.url } });
    return false;
    }

3 个答案:

答案 0 :(得分:1)

您应该使用subscribe等待结果

 this.userService.isLoggedIn(user).subscribe(isSuccess => {
  if (isSuccess) {
    return true;
   }
  else{
      return false;
    }
  }
});

答案 1 :(得分:0)

您必须使用async/await来确保canActivate等到服务器请求解决。以下示例代码可为您提供帮助:

/* UserService */
isLoggedIn(user): Observable<boolean> {
  // check if user is logged in
  return isUserLoggedIn;
}

/* Guard */
async canActivate(route: ActivatedRouteSnapshot, 
  state: RouterStateSnapshot): Promise<boolean> {
const user = JSON.parse(localStorage.getItem('currentUser'));
if (user !== null && !user.isNotAdmin) {

  const isUserLoggedIn: boolean = await this.userService.isLoggedIn(user).toPromise();
  // toPromise() converts Observable to Promise (async/await only works on Promises)
  // the code 'waits' at the above line till the seriver request is resolved

  return isUserLoggedIn;

} else {
  // not logged in so redirect to login page with the return url
  this.router.navigate([''], { queryParams: { returnUrl: state.url } });
    return false;
}

如果您想进一步阅读,请参考:

答案 2 :(得分:0)

更高版本的 Angular 可以从 Observable 方法返回一个 canActivate,使这变得更加容易。如果在 localStorage 中未找到用户,则立即返回,如果找到用户,则调用服务方法。 pipetap 用于拦截它,如果它返回 false,它也会导航到 ''

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<any> {
  const user = JSON.parse(localStorage.getItem('currentUser'));
  if (user === null || user.isNotAdmin) {
    return false;
  }

  return this.userService.isLoggedIn(user).pipe(
    tap((isLoggedIn) => {
      if (!isLoggedIn) {
        this.router.navigate([''], { queryParams: { returnUrl: state.url } });
      }
    })
  }
}

PS:从 localStorage 检查管理员状态不是很安全,但当然取决于您的项目是否可以接受风险。