如何在Chrome中重定向到Angular2路由的canActivate中的外部URL,同时保持Referrer?

时间:2018-05-03 19:20:56

标签: angular google-chrome angular5 url-redirection angular4-router

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

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

所以我设置了路线并将我的Guard服务作为路线的canActivate条件。我用

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

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

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

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

  1. window.location.href = "...";
  2. canActivate返回false。
  3. 由于路由无法激活,因此用户将被删除到应用根目录。
  4. 一瞬间,重定向发生。
  5. 但是因为我们登陆了应用根FIRST,所以推荐人标题是错误的。

    那么我的选择是什么?

    1. 如果我返回true而不是false,则重定向确实会发生 正确的标题,但它不是最安全的东西。
    2. 如果我将查询参数与原始网址一起使用,我需要在我的应用和授权服务之间建立一个中介,将其转换回推荐人标题。
    3. 我可以使用auth服务URL创建一个Anchor标记,然后以编程方式单击它,而不是窗口位置。这似乎会使路由器短路并阻止canActivate完全展开。
    4. 我还能做什么?也许某种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;
              }
      ...
      }
      

0 个答案:

没有答案