【问题标题】:Angular - How to combine AuthGuard and RoleGuardAngular - 如何结合 AuthGuard 和 RoleGuard
【发布时间】:2022-01-10 18:54:15
【问题描述】:

在 Angular-13 项目中,我拥有三个角色:管理员、教师和学生。用户只能拥有一个角色。

我的用户模型的响应如下所示:

user.ts:

export interface IResponse<T> {
  message: string;
  code: number;
  results: T;
}

export interface IUser {
  token?: string;
  roles?: string[];
}

授权服务:

export class AuthService {
  baseUrl = environment.apiUrl;
  constructor(private http: HttpClient, private router: Router) { }

  login(model: any){
    return this.http.post<IResponse<IUser>>(this.baseUrl+'auth/login', model).pipe(
      tap((response)=>{
        const user = response.results;
    return user;
      })
    )
  }

  getToken(): string | null {
    return localStorage.getItem('token');
  } 

  isLoggedIn() string | null {
    return this.getToken();
  } 
}

当用户登录时,令牌和角色存储在localStorage中。此外,用户还会根据角色重定向到仪表板。

login.component:

login(){
 this.authService.login(this.loginForm.value).subscribe({
  next: (res: any) => {
if (res.result.roles[0] == 'Admin'){
     this .router.vavigateByUrl('/admin-dashboard');
    } else if (res.result.roles[0] == 'Teacher'){
     this .router.vavigateByUrl('/teacher-dashboard');
    }else {
     this .router.vavigateByUrl('student-dashboard');
    }
     localStorage.setItem('token', JSON.stringify(res.result.token));
     localStorage.setItem('role', JSON.stringify(res.result.role[0]));
   }
  })
}

auth.guards:

export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private toastr: ToastrService, private router: Router) { }

canActivate(route: ActivateRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
if (!this.authService.isLoggedIn()) {
      this.toastr.info('Please Log In');
      this.router.navigate(['/login']);
      return false; 
    }
    this.authService.isLoggedIn()
    return true
  }
}

app-routing.module:

const routes: Routes = [
  {path: '', redirectTo: 'login', pathMatch: 'full'},
  {path: 'teacher-dashboard', canActivate: [AuthGuard], loadChildren: () => import('./feature/teacher/teacher.module').then(m => m.TeacherModule)},
  {path: 'login', loadChildren: () => import('./feature/login/login.module').then(m => m.AuthModule)},
  {path: 'student-dashboard', canActivate: [AuthGuard], loadChildren: () => import('./feature/student/student.module').then(m => m.StudentModule)},
  {path: 'admin-dashboard', canActivate: [AuthGuard], loadChildren: () => import('./feature/admin/admin.module').then(m => m.AdminModule)},
];

如上所示,我已经使用 AuthGuard 保护了路由。我如何仍然使用 Role 保护路由,以便学生不会进入教师仪表板、管理员仪表板,反之亦然?

谢谢

【问题讨论】:

    标签: angular guard


    【解决方案1】:

    canActivate 需要一个 Guard 数组。所以你的 RoleGuard 可以添加到 AuthGuard 旁边,你应该很高兴。

    {path: 'teacher-dashboard', canActivate: [AuthGuard, RoleGuard], loadChildren: () =&gt; import('./feature/teacher/teacher.module').then(m =&gt; m.TeacherModule)}

    由于守卫是串行执行的,因此您的 RoleGuard 可以简单地获取有关登录用户的角色信息并进行相应的重定向。

    role.guard.ts

    canActivate(): boolean {
      if (localStorage.get('role') === 'teacher') {
        return true;
      }
      return this.router.navigate('some other url');
    }
    

    仅供参考,您将两个项目设置为相同的键:

    localStorage.setItem('token', JSON.stringify(res.result.token));
    localStorage.setItem('token', JSON.stringify(res.result.role[0])); // make it 'role'
    

    【讨论】:

    • 刚刚发生了一些奇怪的事情。使用 RoleGuard,它不会路由。但是如果我删除 RoleGuard,它会路由
    • 这应该意味着 localStorage 中没有设置“角色”,或者密钥放错了位置。
    猜你喜欢
    • 2020-03-02
    • 1970-01-01
    • 1970-01-01
    • 2020-06-20
    • 1970-01-01
    • 1970-01-01
    • 2021-06-16
    • 2015-02-13
    • 1970-01-01
    相关资源
    最近更新 更多