我有一个带有 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$
。我验证并在没有存储令牌时在服务器中成功返回,否则。当它为真时,自导航完成后一切正常。Observable
BehaviorSubject
false
true
浏览器中的方法authService.login
调用OAuthService.initCodeFlow
方法。在服务器中,它是一个空方法。