【问题标题】:One infinite redirect loop in an Angular applicationAngular 应用程序中的一个无限重定向循环
【发布时间】:2019-03-20 05:50:24
【问题描述】:

我正在使用以下路由做一个 Angular 应用程序:

const routes: Routes = [
  {
    path: '',
    component: LoginLayoutComponent,
    children: [
      {
        path: '',
        redirectTo: 'login',
        pathMatch: 'full'
      },
      {
        path: 'login',
        component: LoginComponent
      }
    ]
  },
  {
    path: '',
    component: HomeLayoutComponent,
    canActivate: [AuthGuardService],
    children: [
      {
        path: 'users',
        component: UsersComponent,
      },
      {
        path: 'detail/:id',
        component: UserComponent,
      },
      {
        path: 'dashboard',
        component: DashboardComponent,
        data: {
          expectedRole: 'admin'
        }
      },
      {
        path: 'home',
        loadChildren: './views/home/home.module#HomeModule',
        data: {
          preload: true,
          delay: false
        }
      },
      {
        path: 'error',
        component: ErrorComponent
      },
    ]
  },
];

如果我没有登录并且我请求任何安全 URL,例如 http://localhost:4200/usershttp://localhost:4200/dashboard,那么会重定向到 http://localhost:4200/,并且应用程序会进入无限循环。如果我已登录,则可以正常工作。

浏览器控制台显示以下消息Navigation triggered outside Angular zone

这是我的auth guard 服务:

  canActivate(route: ActivatedRouteSnapshot): Observable<boolean> {
    const expectedRole = route.data.expectedRole ? route.data.expectedRole : null;
    const tokenPayload = this.tokenService.getDecodedAccessToken();
    return this.authService.isAuthenticated()
    .pipe(
      map(isAuth => {
        if (!isAuth) {
          this.router.navigate(['login']);
          return false;
        } else {
          return true;
        }
      }),
      catchError((error, caught) => {
        return of(false);
      })
    );
  }

  canLoad(): Observable<boolean> {
    if (this.authService.isAuthenticated()) {
      return of(true);
    } else {
      return of(false);
    }
  }

我在Angular 7

编辑:现在通过以下身份验证保护解决了该问题:

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.authService.isAuthenticated()
    .pipe(
      map(isAuthenticated => {
        if (!isAuthenticated) {
          this.authService.setPostLoginRedirectUrl(state.url);
          this.router.navigate(['login']);
          return false;
        } else {
          return true;
        }
      }),
      catchError((error, caught) => {
        return of(false);
      })
    );
  }

以及以下路线:

const routes: Routes = [
  {
    path: '',
    component: LoginLayoutComponent,
    children: [
      {
        path: '',
        redirectTo: 'login',
        pathMatch: 'full'
      },
      {
        path: 'login',
        component: LoginComponent
      }
    ]
  },
  {
    path: '',
    component: HomeLayoutComponent,
    canActivateChild: [AuthGuardService],
    children: [
      {
        path: 'users',
        component: UsersComponent,
      },
      {
        path: 'detail/:id',
        component: UserComponent,
      },
      {
        path: 'dashboard',
        component: DashboardComponent,
        data: {
          expectedRole: 'admin'
        }
      },
      {
        path: 'home',
        loadChildren: './views/home/home.module#HomeModule',
        data: {
          preload: true,
          delay: false
        }
      },
      {
        path: 'error',
        component: ErrorComponent
      },
    ]
  },
];

【问题讨论】:

  • 您的LoginLayoutComponent 和您的HomeLayoutComponent 具有相同的路径:''
  • 这是因为他们有子路由。有关示例,请参见 stackoverflow.com/a/46531192/958373
  • 我认为@user184994 是对的。即使它们有子路由,您也需要指定父路由的名称。
  • @Stephane 重定向到内部登录的目的是什么?另外,如果您没有登录并尝试访问不受保护的路径,会发生什么情况?
  • 我解决了这个问题,但无法解释如何。

标签: angular


【解决方案1】:

编辑:找出罪魁祸首!在 app.module.ts 你需要先导入 AuthModule。这样做将允许您在“auth-routing.module.ts”或“app-routing.module.ts”中使用路径“**”

@NgModule({

  imports: [
    AuthModule,
    AppRoutingModule,
    BrowserModule,
    HttpClientModule,
    SharedModule
  ],
})

我也遇到了无限循环问题。不确定这是否与您的有关,但对我来说,我有两个路由文件。 'app-routing.module.ts' 和 'auth-routing.module.ts'。我将下面的代码从“app-routing.module.ts”移动到“auth-routing.module.ts”,不再有无限循环!希望这对您有所帮助!

 {
    path: '**',
    redirectTo: 'my-route',
  }

【讨论】:

    【解决方案2】:

    在我的情况下(主题类似),当我得到循环时,它是登录路由上的 AuthGuard。

    { 路径:'登录', 组件:登录表单组件, canActivate: [AuthGuard], }

    为了解决这个问题,我刚刚从登录路径中移除了守卫。

    【讨论】:

      【解决方案3】:

      对于我的问题,导入顺序会影响此错误。

      @NgModule({
        declarations: [AppComponent],
        imports: [
          BrowserModule,
          BrowserAnimationsModule,
          CommonModule,
      
          AccountModule, // Load other eager modules first
          AppRoutingModule // Move this AppRouting to the end like this
        ],
        providers: [],
        bootstrap: [AppComponent]
      })
      export class AppModule {}
      

      【讨论】:

        【解决方案4】:

        我没有确切的解决方案给你,只是一些调试建议。尝试将其表达为:

        const routes: Routes = [
        {
          path: '',
          component: LoginLayoutComponent,
          children: [
            {
              path: 'login',
              component: LoginComponent
            },
            {
              path: '',
              component: LoginComponent,
              pathMatch: 'full'
            },
          ]
        }
        

        看看是不是路由重定向。

        尝试将其替换为,

        this.router.navigateByUrl('/login');
        

        this.router.navigate(['', 'login']);
        

        【讨论】:

          【解决方案5】:

          redirectTo 值应始终以 / 开头,因为它表示用户应导航到的实际路线。

          在您的路由配置中将 redirectTo: 'login', 更改为 redirectTo: '/login',

          还有,这个:

          this.router.navigate(['login']);
          

          应该是

          this.router.navigate(['/login']);
          

          【讨论】:

          • 我添加了斜杠前缀,但在这个问题上没有任何改变。同样,该问题仅在未登录时出现。
          • navigate内部不需要斜线前缀,即navigateByUrl()
          猜你喜欢
          • 1970-01-01
          • 2015-04-28
          • 1970-01-01
          • 2017-02-03
          • 1970-01-01
          • 1970-01-01
          • 2014-03-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多