使用Auth Guard实现登录前多条件校验(含员工身份判断)
问题原因
你之前的写法错误来源于异步逻辑的执行顺序问题:this.auth.user$是 Observable 异步流,subscribe 内的赋值回调不会立刻执行,你后续同步判断this.isEmployee的时候,回调还没触发,变量自然是undefined。
你不需要单独订阅user$,直接在原有的RxJS管道流里处理多条件校验即可,canActivate本身支持直接返回Observable<boolean | UrlTree>类型,完全可以把所有校验逻辑都放在流内处理。
正确实现代码
export class AuthGuard implements CanActivate { constructor( private auth: AuthService, private router: Router, ) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { return this.auth.user$.pipe( take(1), // 同时校验用户凭证有效 + 用户是员工身份两个条件 map(user => !!user && !!user.isEmployee), tap(canPass => { if (!canPass) { this.router.navigate(['/login']); } }) ); } }
可选优化(更符合Angular最佳实践)
直接在map中返回UrlTree,不需要手动调用router.navigate,Angular会自动处理跳转逻辑,还可以针对不同校验失败原因跳转到不同页面:
export class AuthGuard implements CanActivate { constructor( private auth: AuthService, private router: Router, ) {} canActivate( route: ActivatedRouteSnapshot, state: RouterStateSnapshot ): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree { return this.auth.user$.pipe( take(1), map(user => { // 未登录,跳转登录页 if (!user) { return this.router.parseUrl('/login'); } // 已登录但不是员工,跳转无权限提示页 if (!user.isEmployee) { return this.router.parseUrl('/no-permission'); } // 所有准入条件校验通过,放行 return true; }) ); } }
内容的提问来源于stack exchange,提问作者Notation
相关产品推荐
相关产品推荐

