Я делаю веб-приложение в Angular 8, и у меня есть требование показать / скрыть меню на основе назначенного ресурса. Ресурс - это меню / модуль / функция, как хотите. Допустим, у меня есть 3 меню: встречи, уведомления и чаты. Каждый из них является «ресурсом» для клиента, но для нас это особенность проекта Angular с его собственным модулем и маршрутизацией.
Я прочитал несколько статей, в которых показана логика c для активации маршрута на основе ролей (, как этот ), но я не могу заставить его работать, используя наш подход.
Когда пользователь входит на сайт, мы получать информацию с массивом «ресурсов», которые пользователю разрешено просматривать / получать к ним доступ.
{
firstName: "Mario"
resources: ["Appointments", "Notifications", "Chats"]
}
Мы сохраняем эту информацию в сервисе и можем получать данные в любое время.
Как я уже сказал, мы разделили каждый ресурс с его собственным модулем и маршрутизацией, так что это наш app-routing.module.ts :
const routes: Routes = [
{path: '', redirectTo: 'appointment/administration', pathMatch: 'full'},
{
path: '',
component: AdminLayoutComponent,
canActivate: [AuthGuard], // Checking to see if you are logged in.
children: [
{
path: '',
canActivateChild: [AuthGuard], // Checking to see if you are logged in.
children: [
{
path: '',
loadChildren: () => import('./modules/appointment/appointment.module').then(m => m.AppointmentModule),
canLoad: [AuthGuard] // Only load the module if the user is allow to access.
},
{
path: '',
loadChildren: () => import('./modules/chat/chat.module').then(m => m.ChatModule),
canLoad: [AuthGuard] // Only load the module if the user is allow to access.
},
{
path: '',
loadChildren: () => import('./modules/notification/notification.module').then(m => m.NotificationModule),
canLoad: [AuthGuard] // Only load the module if the user is allow to access.
},
]
}
]
},
];
Маршрутизация каждого модуля выглядит следующим образом: например, модулем уведомлений :
const routes: Routes = [
{
path: 'notification',
// I have added this trying to do the resource based route activation.
// This is the name of this resource to look at it in our AuthGuard.
data: {
resource: 'Notifications'
},
children: [
{
path: 'registry',
component: NotificationRegistryComponent
},
{
path: 'history',
component: NotificationHistoryComponent
},
]
},
];
Наш последний шаг - AuthGuard.
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(
private router: Router,
private authService: AuthService
) {
}
/**
* Requiring authentication.
*/
checkLogin(route?: ActivatedRouteSnapshot): boolean {
const currentUser = this.authService.currentUserValue;
if (currentUser) {
// check if route is restricted by resource
if (route && route.data && route.data.resource && this.checkAuthorization(route, currentUser.resources)) {
// resource not authorised so redirect to home page
this.router.navigateByUrl('/');
return false;
}
// authorised so return true
return true;
}
// not logged in so redirect to login page
this.router.navigateByUrl('/auth/login');
return false;
}
/**
* Checks if the user is allow to access this resource.
*/
checkAuthorization(route: ActivatedRouteSnapshot, allowedResources: string[]): boolean {
const currentResource: string = route.data.resource;
return allowedResources.some(r => r.toLowerCase() === currentResource.toLowerCase());
}
canActivate(
route: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.checkLogin(route);
}
canActivateChild(
childRoute: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {
return this.canActivate(childRoute, state);
}
canLoad(
route: Route,
segments: UrlSegment[]
): Observable<boolean> | Promise<boolean> | boolean {
return this.checkLogin();
}
}
Мы можем войти в наши разрешенные ресурсы, но, мы также можем войти в недопустимые ресурсы и, конечно же, Файл загружен.
Наша цель - иметь доступ только к нашим разрешенным ресурсам, и если вы пытаетесь получить доступ к запрещенному ресурсу, введя URL-адрес вручную в браузере, избегайте загрузки модуля и перенаправления. пользователь на один из его разрешенных ресурсов.