Один из подходов - использование data
свойства Route . Вы можете прикрепить пользовательские значения к любому маршруту. В вашем примере вы можете создать свойство с именем roles
, которое можно использовать в вашем canActivate()
. В следующем примере массив ролей добавляется к маршруту для TasksComponent. В охране мы можем извлечь roles
из next.data.roles
, а затем проверить, что роли, возвращаемые из Firebase, присутствуют и активны:
Маршрут:
{
path: 'tasks',
component: TasksComponent,
data: {
roles: ['admin', 'subscriber']
}
canActivate: [RoleGuard]
}
Охрана:
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | boolean {
const routeRoles = next.data && next.data.roles; // ['admin', 'subscriber']
return this.authService.getAuthWithProfile().pipe(
map((data) => {
const roles = data.roles; // { admin: true, current: false }
const activeRoles = Object.entries(roles).filter(([role, isActive]) => isActive).map(([role, isActive]) => role); // ['admin']
return routeRoles.some(routeRole => activeRoles.includes(routeRole)); // true
})
);
}
}
data.roles
на маршруте не обязательно должен быть массив, вместо этого он может быть объектом, и вы можете подходить к проверке существования активированного маршрута любым удобным для вас способом. Например, если есть только одна роль:
{
path: 'tasks',
component: TasksComponent,
data: {
role: 'admin'
}
canActivate: [RoleGuard]
}
canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> | boolean {
const routeRole = next.data && next.data.role; // 'admin'
return this.authService.getAuthWithProfile().pipe(
map((data) => {
const roles = data.roles; // { admin: true, current: false }
const activeRoles = Object.entries(roles).filter(([role, isActive]) => isActive).map(([role, isActive]) => role); // ['admin']
return routeRoles.includes(routeRole); // true
})
);
}
}
Надеюсь, это поможет!