Angular 12中未登录用户访问需鉴权页面时跳转登录页实现问题
问题根因与修复方案
现有代码错误点
- 权限判断逻辑完全颠倒:当前代码逻辑是「用户不属于任意三个角色之一就返回true放行」,和需求完全相反
- 逻辑运算符使用错误:用
||(或)判断三个角色的包含关系,该条件永远为真(用户不可能同时拥有三个角色),导致所有访问都会被放行 - 缺少登录态校验:没有先判断
currentUser$是否返回了有效用户,未登录用户访问时会直接抛出空指针异常 - 跳转目标不符合需求:权限校验不通过时跳转到了根路径
/,而非要求的登录页/login - 路由守卫未注册(大概率遗漏):Angular的路由守卫必须在模块的
providers数组中注册才会生效
修复后代码
admin.guard.ts(注意你原文件名拼写错误为gurd,建议修正)
export class AdminGuard implements CanActivate { constructor(private accountService: AccountService, private toastr:ToastrService,private router:Router) { } canActivate(): Observable<boolean>{ return this.accountService.currentUser$.pipe( // 建议加take(1)取第一次值就结束订阅,避免内存泄漏 // take(1), map((user:User)=>{ // 先判断用户是否已登录 if(!user) { this.router.navigate(['/login']); this.toastr.error("请先登录后访问该页面"); return false; } // 判断用户是否属于三个合法角色中的任意一个 const validRoles = ['Administrator','Customer','Seller']; if(validRoles.some(role => user.role.includes(role))) { return true; } // 角色权限不足时跳转 this.router.navigate(['/login']); this.toastr.error("您没有权限访问该页面"); return false; }) ) } }
模块注册补充(以AppModule为例)
@NgModule({ declarations: [ // 你的其他组件声明 ], imports: [ AppRoutingModule, // 你的其他模块引入 ], providers: [AdminGuard], // 必须添加该行注册守卫,否则不生效 bootstrap: [AppComponent] }) export class AppModule { }
额外注意事项
如果你的user.role是单角色字符串而非数组,把includes判断改成直接相等判断即可。
内容的提问来源于stack exchange,提问作者adel Ibrahim
相关产品推荐
相关产品推荐

