等待身份验证请求完成,然后检查用户是否使用路由卫士登录

时间:2019-07-18 03:10:04

标签: angular rxjs angular-router angular-router-guards

编辑如下

我不想在每次更改路线时都打电话来确定用户是否已通过身份验证,但是我想检查一下,如果他们刷新了经过身份验证的路由上的页面,他们是否可以访问它。我似乎无法完成这项工作。

我有一项服务,可以简单地检查与api的会话,如下所示:

    authenticate(): Observable<boolean> {
        return this.http.post<boolean>(this._authUrl, {}, {})
    }

端点从字面上返回truefalse。我在app.component上运行它,因此这是第一件事,它不再需要再次请求。

   ngOnInit() {
        this.userService.authenticate().subscribe((response) => {
            this.userService.loggedIn = response;
        })

    }

然后我定义了一条这样的路线:

    {
        path: 'dashboard',
        component: DashboardComponent,
        canActivate: [AuthGuardService],
        pathMatch: 'full'
    },

然后在我的authguard服务中,我有这个:

canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): any{
    return this.userService.loggedIn
    })
}

如果您登陆/并导航至/dashboard,此方法就很好了。但是,如果您登录并刷新/dashboard上的页面,该组件将永远不会加载。它会加载导航等内容,但不会加载仪表板组件或模板。 /authenticate确实可以运行,但是在端点响应之前,路由保护程序似乎已经查看loggedIn

我尝试使用loggedInof变量放入一个可观察的对象,这似乎没有什么区别,最终结果是相同的。

我查找的所有内容似乎都是用于通过URL检查身份验证并以这种方式使用可观察对象,但是当它已经知道用户从第一个初始名称进行身份验证时,我真的不想发出http请求请求。

编辑: 我认为,考虑此问题的更好方法是,我希望/authenticate响应在加载其他任何内容之前已经准备好。使用Route Guard,我必须将登录页面锁定在登录之后,而我不想这样做。但是我也希望根/authenticate可以访问app.component的响应,因为那是我的导航所在,也是用户登录的指示器。

因此,对我来说似乎有意义的是,如果我可以告诉angular在完成所有操作之前先在​​/authenticate上等待,即使他们刷新了{{1}上的页面},/dashboard响应已经在那里,因此我不必担心这种令人讨厌的比赛条件。我可以这样做吗?

1 个答案:

答案 0 :(得分:-1)

我会做这样的事情:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean>  {
    return new Promise<boolean>((resolve, reject) => {
      if (this.getUser) this.getUser.unsubscribe();
      this.getUser = this.authService.getUser().subscribe(r => {
        resolve(true);
      }, (err) => {
        reject(err);
      });
    });
  }

这:

getUser(): Observable<UserDTO> {
    if (this.user) return new Observable(o => o.next(this.user));
    return this.http.get<UserDTO>(URL, { withCredentials: true })
      .pipe(
        map(u => new UserDTO(u)),
        tap(u => {
          this.user = u;
          this.isLogined = true;
        })
      );
  }

并从组件中删除逻辑。这一定要警惕。