0

我有一个带有 SSR 的 Angular 应用程序,其中所有路由都受到保护,并且 RouterinitialNavigation属性设置为enabled. 我正在使用带有代码流 + PKCE的angular-oauth2-oidc包。所有路由都是延迟加载的,我有一个CanActivateChild警卫检查用户是否经过身份验证。

在浏览器中时,CanActivateChild检查它是否已通过身份验证,如果未通过,它会重定向到 Azure AD B2C 以执行身份验证。这在没有 SSR 的情况下运行良好。

在服务器中,CanActivateChild如果它没有经过身份验证,它只是通过返回来取消导航,false但没有重定向。这个想法是返回没有激活的路由,只渲染/引导根组件,因为它没有经过身份验证,让浏览器处理身份验证。我把它留给浏览器,因为angular-oauth2-oidc是针对浏览器平台的,其中的一些功能在OAuthService服务器上不起作用,因为它依赖于一些浏览器 API,我确实有OAuthStorage每个平台的实现,所以我可以得到每个平台上的代币。使用此设置,Express.js 服务器不会响应,我认为这是因为应用程序的引导正在等待导航完成,initialNavigation因为enabled. 我希望这能正常工作,因为从某种意义上说,取消也是导航的完成。

我可以考虑几种解决方法,比如禁用initialNavigation哪个不好,因为这会导致页面闪烁(所以它不是),或者重定向到一个空组件只是为了完成导航,或者手动重定向服务器到 Azure AD B2C 授权端点等。

有没有人遇到过这个并有更好的解决方案?我错过了什么还是我配置错误?

编辑,添加一些片段:

身份验证:

canActivateChild(
    _: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    return this.authService.isAuthenticated$.pipe(
      tap((isAuthenticated) => isAuthenticated || this.authService.login(state.url)),
    );
  }

如果令牌在 cookie 中,则服务器仅发送它authService.isAuthenticated$。我验证并在没有存储令牌时在服务器中成功返回,否则。当它为真时,自导航完成后一切正常。ObservableBehaviorSubjectfalsetrue

浏览器中的方法authService.login调用OAuthService.initCodeFlow方法。在服务器中,它是一个空方法。

4

0 回答 0