我们应该在 Angular 身份验证守卫中使用 Auth API 执行什么身份验证检查?

What authentication check using the Auth API should we perform in our Angular Authentication Guards?

In this article 作者在 AuthGuard 中使用 Auth.currentAuthenticatedUser() 是这样的:

  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return Auth.currentAuthenticatedUser().then(() => { return true; })
      .catch(() => {
        this.router.navigate(['signin']);
        return false;
      });
  }

但是 as noted in this issue 即使使用已通过身份验证并已重定向,这也可能会抛出错误,从而导致两次重定向。第一个来自 Cognito,第二个来自 auth guard,因为它 "Think" 用户尚未登录。

那么我们应该在 Auth 上调用什么来保证在用户通过联合身份登录时不会抛出异常?

我认为 Auth.currentSession() 可以,但想仔细检查一下。

更新

我试过 Auth.currentSession() 但它也没有在重定向后立即提供会话。

这是我在 AppComponent 中尝试过的:

    Auth.currentSession().
      then((s) => console.log(`The current session is ${JSON.stringify(s)}`)).
      catch((e) => console.log(`There is no current session ${e}`))



应用程序加载后重定向后,记录的内容如下:

There is no current session No current user

如果我手动刷新,它会按照我们的预期记录一个会话。

一般来说,我们可能不会假设经过身份验证的用户在 Cognito 重定向后立即可用。

由于我们不能这样做,我们也不能重定向到受保护的资源,因为守卫拒绝访问。

因此我们必须重定向到一个不受保护的页面,然后等待 Amplify 告诉我们身份验证已经发生。

然后我们可以使用 Subject 来通知应用程序的其他部分。

似乎正确的收听方式(直到 Angular 9 得到 Angular 服务的支持)是 运行 Auth.currentAuthenticatedUser() 和 Hub.listen并行.

在重定向之后 Auth.currentAuthenticatedUser() 很可能会抛出异常,但 Hub.listen 最终会发出登录事件,我们接下来可以在我们的主题上执行该事件。

所以尝试 Auth.currentAuthenticatedUser() 如果它抛出,则尝试在 catch 块中使用 Hub 侦听 sigin 事件。在这种情况下还要监听 signout 事件。

在那之后,直到用户注销或会话超时,Auth.currentAuthenticatedUser() 应该总是 return 一个用户,然后我们可以在我们用来观察身份验证状态的主题上进行下一步。

这就是我打算处理它的方式。