Angular 17 AuthGuard 与 Observable

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

如果用户未登录,则尝试让以下 AuthGuard 正确重定向。

export const authGuard: CanActivateFn = (route, state) => {
  const authService = inject(AuthService);
  const router = inject(Router);

  return authService.currentUser$.pipe(map((auth: User | null) => {
    console.log(auth);
    if(auth !== null){
      console.log(auth);
      return true;
    }
    return router.createUrlTree(['/login']);
  }));
};

在我的 AuthService 文件中我使用以下内容

private currentUserSource = new ReplaySubject<User | null>(1);
currentUser$ = this.currentUserSource.asObservable();

在我的 app.routes.ts 文件中,我的测试组件正在延迟加载。

{path: 'test', loadComponent: () => import('./test/test.component').then(mod => mod.TestComponent), canActivate: [authGuard]},

它没有将用户重定向到登录页面,而是仅显示一个空白页面。

谢谢

我用不同的方法重写了几次,但都未能重定向。

angular angular-routing angular-router angular-guards
2个回答
0
投票

我尝试在 stackblitz 上复制您的问题,并且在使用功能防护时,我遇到了“没有 authguard 提供程序”,其中会返回黑色页面。

所以我把功能性的authguard变成了类守卫,并在

root

中提供

看这里:

https://stackblitz.com/edit/angular-standalone-route-fhto46?file=src%2Froutes%2Froutes.ts


@Injectable({ providedIn: 'root' })
class AuthGuardClass implements CanActivate {
  private router = inject(Router);
  canActivate() {
    return of({ user: 'mock' }).pipe( // Replace mock
      map((auth: { user: string } | null) => {
        console.log(auth);
        if (auth !== null) {
          console.log(auth);
          return true;
        }
        return this.router.createUrlTree(['/login']);
      })
    );
  }
}

export const routes: Routes = [
  {
    path: '',
    canActivate: [AuthGuardClass],
    children: [
      {
        path: '',
        pathMatch: 'full',
        redirectTo: 'home',
      },
      {
        path: 'home',
        loadComponent: () =>
          import('./home.component').then((mod) => mod.HomeComponent),
      },
    ],
  },
  {
    path: 'login',
    loadComponent: () =>
      import('./login.component').then((mod) => mod.LoginComponent),
  },
];

0
投票

我认为问题可能是使用

ReplaySubject
作为您的
currentUserSource
变量,我建议将其替换为
BehaviourSubject
:

private currentUserSource = new BehaviourSubject<User | null>(null);
currentUser$ = this.currentUserSource.asObservable();

至于为什么我认为这可能是问题的根源,导致空页锁定的防护通常意味着它等待

Observable
发出值,您的
ReplaySubject
不保留默认值,这将导致如果
authGuard
User
均未发出,则阻止您的
null
执行任何操作。

将其更改为

BehaviourSubject
将确保始终有一个值,因此守卫可能始终能够完成。

© www.soinside.com 2019 - 2024. All rights reserved.