角度路由,从未找到页面重定向到登录页面

问题描述 投票:0回答:1

我的路由器无法正常工作,当我转到 pageNotFound 页面并想要返回之前的步骤时,它会将我重定向到登录页面,如果您提供有关如何修复它的提示,我将不胜感激。反编译显示,从该页面返回时,authenticationguard - canActive() 中的方法返回 false,不幸的是我无法找出为什么用户读取不正确

export const routes: Routes = [
      {
        path: 'forbidden',
        component: ForbiddenPageComponent,
      },
      {
        path: 'auth',
        loadChildren: () => import('./modules/auth/auth.module').then(mod => mod.AuthModule),
        component: AuthComponent,
      },
     
      {
        path: '',
        canActivate: [AuthenticationGuard],
        canActivateChild: [AuthorizationGuard],
        children: [
          {
            path: 'task',
            loadChildren: () => import('./modules/task/task.module').then(mod => mod.TaskModule),
          },
          {
            path: 'order',
            loadChildren: () => import('./modules/order/order.module').then(mod => mod.OrderModule),
          },
          {
            path: '',
            pathMatch: 'full',
            redirectTo: 'task',
          }
        ],
      },
      {
        path: '**',
        pathMatch: 'full',
        component: PageNotFoundComponent
      }
    ];

@Injectable({
  providedIn: 'root',
})
export class AuthenticationGuard {
  currentUser: OPLUser | null;
 
  constructor(
    private authService: AuthService,
    private router: Router,
    @Inject(APP_CONFIG) private appConfig: AppEnvConfiguration
  ) {
    this.authService.currentUser$.subscribe(user => {
      this.currentUser = user;
    });
  }
 
  canActivate(): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    if (this.appConfig.skipLogin || (this.currentUser && this.currentUser.isAuthenticated())) {
      return true;
    }
 
    this.router.navigate(['/auth'], { replaceUrl: true });
 
    return false;
  }
}

@Injectable({
  providedIn: 'root',
})
export class AuthorizationGuard {
  constructor(
    private authService: AuthService,
    private router: Router,
    @Inject(APP_CONFIG) private appConfig: AppEnvConfiguration
  ) {}
 
  /**
   * Checks if user is authorized to activate this route.
   * If not, user is redirected to 'forbidden' page.
   *
   * @param route
   */
  canActivateChild(
    route: ActivatedRouteSnapshot
  ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
    const currentUser = this.authService.currentUser$.getValue();
    if (currentUser && currentUser.authenticatedAndAuthorized) {
      if (this.appConfig.skipLogin) return true;
 
      const routeRoleList: RouteRule = route && route.data ? route.data['roleList'] : null;
 
      if (!routeRoleList || this.matchesRole(routeRoleList, currentUser)) {
        return true;
      } else {
        this.router.navigate(['forbidden'], { skipLocationChange: true });
        return false;
      }
    } else {
      this.router.navigate(['forbidden'], { skipLocationChange: true });
      return false;
    }
  }
 
  /**
   * Checks if user roles matches route role configuration.
   * OneOf - checks any role.
   * AllOf - checks all roles.
   *
   * @param routeRoleList - provided route role configuration.
   * @param user - current user.
   */
  matchesRole(routeRoleList: RouteRule, user: OPLUser | null): boolean {
    let match = true;
 
    if (routeRoleList.oneOf && routeRoleList.oneOf.length > 0) {
      match = routeRoleList.oneOf.some(role => user?.hasRole(role));
    }
 
    if (routeRoleList.allOf && routeRoleList.allOf.length > 0) {
      match = routeRoleList.oneOf.every(role => user?.hasRole(role));
    }
 
    return match;
  }
}
 
angular routes authorization guard
1个回答
0
投票

发生这种情况是由于您配置路由的顺序所致。 Angular 路由器将按照当前 url 的顺序评估您在路由配置对象中定义的路径。这里发生的情况是路由器遇到了你的子路径和与 url 匹配的空路径(因为你没有

pathMatch: full
)。然后,它会尝试根据那里的重定向将您路由到
/task
,该重定向受
AuthenticationGuard
保护,因此您会被重定向到登录。

有两种方法可以解决此问题:

  1. 您可以将包罗万象的路线(
    **
    )移动到空路线上方,如下所示:
      ...
      {
        path: '**',
        pathMatch: 'full',
        component: PageNotFoundComponent
      },
      {
        path: '',
        canActivate: [AuthenticationGuard],
        canActivateChild: [AuthorizationGuard],
        children: [
          {
            path: 'task',
            loadChildren: () => import('./modules/task/task.module').then(mod => mod.TaskModule),
          },
          {
            path: 'order',
            loadChildren: () => import('./modules/order/order.module').then(mod => mod.OrderModule),
          },
          {
            path: '',
            pathMatch: 'full',
            redirectTo: 'task',
          }
        ],
      },
      ...
  1. 您可以将
    pathMatch: full
    添加到空路径,如下所示:
     {
        path: '',
        pathMatch: 'full',
        canActivate: [AuthenticationGuard],
        canActivateChild: [AuthorizationGuard],
        children: [
          {
            path: 'task',
            loadChildren: () => import('./modules/task/task.module').then(mod => mod.TaskModule),
          },
          {
            path: 'order',
            loadChildren: () => import('./modules/order/order.module').then(mod => mod.OrderModule),
          },
          {
            path: '',
            pathMatch: 'full',
            redirectTo: 'task',
          }
        ],
      },

如果您想自己调试路由器,可以通过启用路由器跟踪来实现。它将记录路由器经过的进程到控制台。您可以通过在根级别 app-routing.module.ts 中添加选项来做到这一点,如下所示:

@NgModule({
  imports: [
    RouterModule.forRoot(routes, {
      enableTracing: true
    }),
  ],

如果您使用的是独立的 Angular 应用程序(它使用

bootstrapApplication
方法引导您的 Angular 应用程序,您可以通过包含
withDebugTracing
中的
@angular/router
来启用路由器跟踪,如下所示:

    provideRouter(APP_ROUTES, 
      withDebugTracing(),
    ),
© www.soinside.com 2019 - 2024. All rights reserved.