Angular 6 Route Guard 显示白页

Angular 6 Route Guard Shows White Page

我正在尝试添加一个 Route Guard,它会将 JWT 发送到 PHP API return true 或 false,具体取决于用户是否经过身份验证。通过我的测试,Route Guard 一直工作到它实际调用 API。如果 API return 为假,守卫会按预期工作。但是,如果 API return 为真,那么守卫似乎想要重定向用户,就好像 return 为假一样,但它不显示主屏幕,而是显示什么都没有。

auth.guard.ts

canActivate(): boolean {
    if (localStorage.getItem('portfolioJWT') === null) {
        this.router.navigate(['/']);
        return false;
    } else {
        const token = JSON.parse(localStorage.getItem('portfolioJWT'));

        this.authService.isAuth(token).subscribe(res => {
            console.log(res);
            if(!res) {
                this.router.navigate(['/']);
                console.log("NOT Authorized");
                return false;
            } else {
                console.log("Authorized");
                return true;
            }
        });
    }
}

auth.service.ts

isAuth(token: string): Observable<Boolean> {

  const authHttpOptions = {
      headers: new HttpHeaders({
          'Content-Type': 'application/x-www-form-urlencoded',
          'Authorization': 'Bearer ' + token
      })
  };

  return this.http.post<Boolean>('http://portfolioapi/api/checkAuth', {}, authHttpOptions);
}

我让守卫控制台记录 returned 值,以及用户是否被授权,它确实如此并且显示了正确的数据。

问题可能是您没有为 canActivate 使用 Promise<boolean>,因此当 canActivate 仍在后台执行时, 路由器已经移动,因此触发了意外行为。

一个例子可能是 API returns false 并初始化一个 navigate,但只有在路由器 已经导航 你在某个地方(这可能会触发空白页)。 console.log(res) 也是如此。它可能会起作用,但已经太晚了,路由器已经移动了。

您想要实现的是,路由应该暂停,直到收到 true 或 false。在没有 Promise 的情况下检查局部变量的值可能会正常工作,但是在执行 API 调用时 do 很重要,因为它是 asynchronous,因此您明确需要告诉路由器等待呼叫完成。

canActivate(): Promise<boolean> {
    return new Promise((resolve) => {
        if (localStorage.getItem('portfolioJWT') === null) {
            this.router.navigate(['/']);
            resolve(false);
        } else {
            const token = JSON.parse(localStorage.getItem('portfolioJWT'));

            this.authService.isAuth(token).subscribe(res => {
                console.log(res);
                if(!res) {
                    this.router.navigate(['/']);
                    console.log("NOT Authorized");
                    resolve(false)
                } else {
                    console.log("Authorized");
                    resolve(true)
                }
            });
        }
    })
}