通过在router.navigate中传递参数来忽略可以激活的防护

问题描述 投票:0回答:2

我正在寻找一种通过传递参数/标志/等来忽略一次性防护的解决方案。在路由器导航中。

当前配置:

  • 带身份验证的标准路由
    canActivate: [CanActivateGuard]
  • 解析器 - 检查子路径应用程序 - 用于加载快照,当用户获得带有某些路径的 URL 时,可以加载应用程序,

问题:

  • 上述机制运行良好(快照、生成丢失的 ngrx 存储数据等)
  • 但在警卫中我正在检查存储中是否存在某些值:
  canActivate(): boolean {
    let canActivate = false;
    this.store$.pipe(select(selectSth), take(1)).subscribe(item => {
      if (!!item) {
        return canActivate = true;
      }
      this.router.navigate(['/main']);
      return canActivate = false;
    });
    return canActivate;
  }
}
  • canActivate 在解析器之前被检查 - 所以我无法导航到
    /main
    路径,即使参数存在于 store

问题:

有什么办法可以给

this.router.navigate
添加参数并一次性避开守卫吗?

angular
2个回答
2
投票

问题是,在 Angular 中,所有守卫都应该在任何解析器之前执行,因此如果您有带有守卫的子路由,它们将阻止父解析器,除非所有守卫都成功。

这个逻辑意味着守卫的数据应该已经存在(App Init)或者由守卫加载。

一个可能的解决方案是将数据加载逻辑移至守卫,如果守卫成功,则相应的解析器将简单地从存储中选择数据。

如果您不打算始终一起使用防护程序和解析器,您可以引入一个在需要时加载数据的服务,并依赖两个类中的服务:防护程序和解析器。


0
投票

您可以在 NavigationExtras 中传递自定义状态:

this.router.navigate(['registration'], { state: { ignoreGuard: true } });

在守卫内部访问如下值:

canActivate(): boolean {
    const state = this.router.getCurrentNavigation()?.extras?.state;
    const ignoreGuard = state && state['ignoreGuard'] as boolean;

    if(ignoreGuard) {
        return true;
    }

    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.