Как вы управляете ролями пользователей и разрешениями с помощью Angular 2
Я работаю над новым приложением Angular2, и мне было интересно, как вы управляете маршрутами, доступными для определенных ролей и разрешений для создания, редактирования и удаления элементов для определенных ролей.
Я хочу знать, как решить эту проблему:
-
Как вы управляете доступом к некоторым элементам пользовательского интерфейса? Как приложение знает, чтобы показать или скрыть это? Используете ли вы один сервис для этого? Или вы создаете разные условия для разных мест в своем приложении?
-
Как вы управляете своей маршрутизацией? Используете ли вы CanActivate, CanActivateChild, CanLoad и т.д.? Вы строите единую охранную службу для всех маршрутов или создаете разные службы для разных модулей или компонентов?
-
И последний вопрос. Каков наилучший способ разделить приложение, тогда вы можете продать его, как CMS? Я имею в виду, как мы можем реализовать возможность загрузки некоторых других модулей с рынка, например, и добавить их в ваше приложение?
Как вы решаете подобную проблему?
Любое руководство, опыт или указатели на материалы, посвященные этим темам, высоко оценены. Заранее спасибо.
Ответы
Ответ 1
Как уже упоминалось в комментариях к вашему вопросу, полный ответ выходит за рамки вопроса/ответа SO, и поэтому вы можете в ближайшем будущем закрыть свой вопрос в ближайшем будущем, но вот несколько быстрых предложений для вас исследовать дальше самостоятельно:
-
Получите разрешения пользователя с сервера во время/после входа через http/https. Храните эти разрешения где-то, что имеет смысл для вашего приложения, возможно, в службе. Если вы используете JWT, разрешения могут быть возвращены в токере JWT.
-
Чтобы упростить ситуацию, разрешайте только разрешения на клиенте. Роли для кода сервера, чтобы выяснить, какие разрешения у пользователя есть. Не нужно гадости, объединяя роли с разрешениями на клиенте.
-
Защита маршрутов с помощью auth-охранников
-
Защитите отдельные элементы пользовательского интерфейса с помощью * ngIf или ngSwitch/* ngSwitchCase
-
Динамическая загрузка - большая область темы - прочитайте об этом - много ресурсов в Интернете. Однако, насколько я знаю, хотя вы можете лениво загружать модули, они должны быть известны приложению во время компиляции. Возможно, я ошибаюсь, но я не думаю, что вы можете просто загружать все, что захотите, во время выполнения.
Ответ 2
Поэтому мне пришлось реализовать что-то подобное в приложении, которое я разработал, вот как я его обработал.
Я создал службу auth, в которой содержался метод, который был проверен: пользователь имел роль управления:
auth.service.ts
public isManager(): boolean {
let isManager = false;
let user = this.getUserToken();
//Stored my allowed groups in a config file, comma separated string
let allowedGroups = AuthenticationParams.filters.split(',');
let userGroups: any;
if (user !== null && user !== undefined) {
try {
let userGroups: any = user.role;
if (userGroups !== undefined && userGroups !== null && userGroups.length > 0) {
try {
userGroups.forEach((e: any) => {
if (allowedGroups.indexOf(e) > -1) {
isManager = true;
}
});
} catch (e) {
if (allowedGroups.indexOf(userGroups) > -1) {
isManager = true;
}
}
}
} catch (e) {
isManager = false;
}
}
return isManager;
}
public getUserToken(): any {
return localStorage.getItem('jwtTokenName');
}
Я создал auth guard следующим образом:
guard.component.ts
import { Injectable, OnInit } from '@angular/core';
import { CanActivate, CanActivateChild } from '@angular/router';
import { Router } from '@angular/router';
import { AuthenticationService } from '../services/helper/security/auth.service';
@Injectable()
export class GuardComponent implements CanActivate {
constructor(private authenticationService: AuthenticationService, private _router: Router) {
}
canActivate() {
let isManager: boolean = this.authenticationService.isManager();
if (!isManager) {
this._router.navigate(['unauthorized']);
}
return isManager;
}
}
guard.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { GuardComponent } from './guard.component';
@NgModule({
declarations: [],
imports: [ CommonModule ],
exports: [],
providers: [ GuardComponent ],
})
export class GuardModule { }
Затем я использовал защитник для моего маршрута, который обрабатывает навигацию в разделе admin
приложение-routing.module.ts
{ path: 'management', component: AdminComponent, canActivate: [GuardComponent] }
В моей навигационной панели я просто вызываю метод isManager
и сохраняю его на переменной и использую, чтобы определить, нужно ли отображать ссылку управления или нет.
navbar.component.ts
public isManager: boolean = false;
ngOnInit(): void {
this.isManager = this.authenticationService.isManager();
}
navbar.component.html
<li [routerLinkActive]="['active']" *ngIf="isManager"><a [routerLink]="['management']">Management Portal</a></li>
Мне пришлось удалить некоторые данные из каждого метода, но это даст вам основную идею. Надеюсь, это поможет.
Ответ 3
Этот вопрос довольно широк, и я не уверен, что вы можете легко его покрыть в этом ответе. В нем есть три вещи
- маршрутизация
- гвардия
- Модули
У вас должен быть один модуль защиты, который будет проверять все приложение, и все вспомогательные маршруты будут дочерними для маршрута охраны. Короче говоря, он будет действовать как глобальная охрана для всего вашего приложения. И ваша маршрутизация будет покрыта коротким. Подробнее о гвардии
И теперь, говоря о модулях, вам нужно разделить все на обычные и функциональные модули и повторно использовать модули или использовать их самостоятельно. Это поможет вам продать его, как CMS. Подробнее о модулях.
Примечание. Это не точный ответ, а суть проблемы.