【问题标题】:Angular router guard with Observable does not work after page refresh带有 Observable 的 Angular 路由器防护在页面刷新后不起作用
【发布时间】:2020-08-20 16:42:29
【问题描述】:

我有下一个 Angular Guard:

export class AdminGuard implements CanActivate {
  constructor(
    private readonly router: Router,
    private readonly userService: UserService
  ) { }

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

      return this.userService.getUserRoles().pipe(
        map(roles => {
          if (roles.admin) {
            return true
          }

          this.router.navigate(['/'])
          return false
        })
      )
  }
}

这是来自服务的方法,它返回 Observable:

  public getUserRoles(): Observable<any> {
    return this.store.pipe(
      select('user'),
      map(({ roles }) => roles)
    )
  }

当我在页面之间导航时这是有效的,但是当我直接在 URL 中输入一些路由时,例如“myapp.com/admin”,它会自动返回 false,并且防护不起作用。如何让它正常工作?

【问题讨论】:

  • 我认为您在刷新后丢失了商店数据,您是否将商店保存在本地存储中?
  • @FatehMohamed 我不确定将用户角色保存到本地存储是否是个好主意。用户只需在浏览器中打开和localstorage,他可以将admin角色更改为true,然后使用admin-panel。
  • 有时你也有刷新的情况,使用github.com/btroncone/ngrx-store-localstorage
  • @VladimirHumeniuk SPA 在浏览器中运行。他们天生不安全;用户可以随时更改浏览器中的代码和数据来做他们想做的事。您唯一可以保护的是后端。当用户向服务器提交更改时,您应该检查用户授权,而不用担心用户入侵本地存储;只需将其视为方便的 UI,以显示他们应该能够对后端执行哪些操作。如果用户阻止本地设置来查看管理面板,这不应损害后端安全性。

标签: angular rxjs angular-routing ngrx angular-guards


【解决方案1】:

最好的猜测是,直接在浏览器中输入 url 时,您正在重新启动应用程序,并且商店将重置为默认值,没有用户。

您应该重写您的getUserRoles() 方法,以在读取角色之前检查用户是否已通过身份验证,而不仅仅是读取存储状态。例如,如果您使用的是 OAuth2,这会将用户重定向到您的身份验证端点,并在重新身份验证握手完成并填充存储后,通过适当的状态在 myapp.com/admin 路由上恢复。

具体情况很大程度上取决于您使用的身份验证方法。

【讨论】:

    猜你喜欢
    • 2019-07-03
    • 2019-02-24
    • 1970-01-01
    • 2018-02-02
    • 2017-10-06
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多