由于Observers在Angular中的深度以及调试那种事情所涉及的困难,我可能会对这里发生的事情略微偏离,但这正是我所观察到的 .

我有一个使用@ angular / router 5.2.6的Angular 5应用程序,我有一个Guard服务,我有一个外部SSO类型的用户身份验证服务 . 如果用户未经过身份验证,我需要能够重定向到我的身份验证服务,如果需要,请登录,然后返回他们最初尝试获取的SAME URL .

所以我有路由设置并将我的Guard服务作为路由的canActivate条件 . 我用

window.location.href = "...";

从我的应用程序重定向到auth服务 . 并且在设置重定向后也从canActivate方法返回false .

我的身份验证服务依赖于Referrer标头,以了解在用户通过身份验证后将用户返回的位置 . 这在大多数浏览器中都可以正常工作,但在Chrome中,似乎浏览器会在执行重定向之前让整个事件堆栈展开 .

这就是说似乎发生的事情是:

  • window.location.href = "...";

  • canActivate返回false .

  • 由于路由无法激活,因此用户将被删除到应用程序根目录 .

  • 一瞬间,重定向发生 .

但是因为我们登陆了应用程序根FIRST,所以Referrer标头错误 .


那么我的选择是什么?

  • 如果我返回true而不是false,重定向确实会发生正确的 Headers ,但这不是最安全的事情 .

  • 如果我将查询参数与原始URL一起使用,我需要在我的应用程序和auth服务之间 Build 一个中介,将其转换回Referrer标头 .

  • 我可以使用auth服务URL创建一个Anchor标记,并以编程方式单击它,而不是窗口位置 . 这似乎会使路由器短路并阻止canActivate完全展开 .

我还可以做些什么?也许某种Observable返回等待popstate或hashchange并强制返回URL?有没有我看不到的东西,你认为我的问题是否正确?


编辑:添加canActivate方法

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    const url: string = state.url;

    if (this.authService.config.permissionsEndpointUrl && this.authService.config.hasUserPermissions) {
      // If permissions are configured, check both the user session token and user access permissions
      return this.checkLogin(url) && this.checkPermissions(route.data['permissions']);
    } else {
      // Otherwise, only check the user session token
      return this.checkLogin(url);
    }
  }



private checkLogin(url: string): boolean {
    const currentUser = this.authService.getUserSessionDetails();
    if (currentUser && currentUser.token && this.authService.tokenNotExpired(currentUser.token)) {
      return true;
    }

    // Store the attempted URL for redirecting after login
    this.authService.redirectUrl = url;

    this.authService.redirectToLogin(true);
    return false;
  }

redirectToLogin(guardMode: boolean = false): void {
...
        if (this.config.loginRoutePath) {
            window.location.href = this.config.loginRoutePath;
        }
...
}