在我的Angular 4项目中,我想使用权限,我从API获得权限。权限保存为带有ID的数组。某些单个元素(如用户或博客帖子)具有允许权限的属性,允许或不允许编辑或删除等操作作为带有ID的数组。
在Angular 4项目中检查和处理权限的最佳方法是什么? Angular中有一些用于权限处理的bos解决方案吗?如果Angular没有一些开箱即用的解决方案,有人可以给我实现权限处理的想法吗?
答案 0 :(得分:8)
Guard
..
记住警卫仅适用于ROUTING ..所以只检查用户是否可以访问路线..但不是基于角色或其他任何内容显示组件中的单个元素...我建议您使用*ngIf
或显示以呈现/显示或不显示某些UI元素...
对于一个基于角色的守卫(不仅如果使用是否认证)..你可以做类似的事情:
import { Injectable } from "@angular/core";
import { AuthService, CurrentUserService } from "app/shared/services";
import { Router, RouterStateSnapshot, ActivatedRouteSnapshot, CanActivate } from "@angular/router";
import { AspNetUsersDTO } from "app/shared/models";
import { Observable } from "rxjs/Rx";
@Injectable()
export class RoleGuard implements CanActivate {
constructor(private authService: AuthService,
private _currentUser: CurrentUserService,
private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
if (!this.authService.isLoggedIn()) {
resolve(false);
return;
}
var currentUser: AspNetUsersDTO = new AspNetUsersDTO();
this._currentUser.GetCurrentUser().then((resp) => {
currentUser = resp;
let userRole = currentUser.roles && currentUser.roles.length > 0 ? currentUser.roles[0].toUpperCase() : '';
let roles = route && route.data["roles"] && route.data["roles"].length > 0 ? route.data["roles"].map(xx => xx.toUpperCase()) : null;
if (roles == null || roles.indexOf(userRole) != -1) resolve(true);
else {
resolve(false);
this.router.navigate(['login']);
}
}).catch((err) => {
reject(err);
this.router.navigate(['login']);
});
});
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
return new Promise<boolean>((resolve, reject) => {
if (!this.authService.isLoggedIn()) {
resolve(false);
return;
}
var currentUser: AspNetUsersDTO = new AspNetUsersDTO();
this._currentUser.GetCurrentUser().then((resp) => {
currentUser = resp;
let userRole = currentUser.roles && currentUser.roles.length > 0 ? currentUser.roles[0].toUpperCase() : '';
let roles = route && route.data["roles"] && route.data["roles"].length > 0 ? route.data["roles"].map(xx => xx.toUpperCase()) : null;
if (roles == null || roles.indexOf(userRole) != -1) resolve(true);
else {
resolve(false);
this.router.navigate(['login']);
}
}).catch((err) => {
reject(err);
this.router.navigate(['login']);
});
});
}
}
然后您可以在路由中使用:
{
path: 'awards-team',
component: AwardsTeamComponent,
canActivateChild: [RoleGuard],
children: [
{
path: 'admin',
component: TeamComponentsAdminComponent,
data: { roles: ['super-admin', 'admin', 'utente'] }
},
{
path: 'user',
component: TeamComponentsUserComponent,
data: { roles: ['utente'] }
}
]
}
答案 1 :(得分:5)
您可以尝试使用ngx-permissions库来控制角度应用程序中的权限。它将从DOM中删除元素的好处。 加载权限的示例
import { Component, OnInit } from '@angular/core';
import { NgxPermissionsService } from 'ngx-permissions';
import { HttpClient } from '@angular/common/http';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
constructor(private permissionsService: NgxPermissionsService,
private http: HttpClient) {}
ngOnInit(): void {
const perm = ["ADMIN", "EDITOR"];
this.permissionsService.loadPermissions(perm);
this.http.get('url').subscribe((permissions) => {
//const perm = ["ADMIN", "EDITOR"]; example of permissions
this.permissionsService.loadPermissions(permissions);
})
}
}
模板中的用法
<ng-template [ngxPermissionsOnly]="['ADMIN']" (permissionsAuthorized)="yourCustomAuthorizedFunction()" (permissionsUnauthorized)="yourCustomAuthorizedFunction()">
<div>You can see this text congrats</div>
</ng-template>
<div *ngxPermissionsOnly="['ADMIN', 'GUEST']">
<div>You can see this text congrats</div>
</div>
<div *ngxPermissionsExcept="['ADMIN', 'JOHNY']">
<div>All will see it except admin and Johny</div>
</div>
答案 2 :(得分:0)
从我个人的角度来看,从API获得许可是用户权限的最佳解决方案。
除了通过使用Router中的canActivate
属性检查权限之外,我还喜欢在导航拦截器中使用检查功能。因为它会在检查不正确的权限时保留网址,而不是url localhost:42000 /#/.../ permission-denied
这是我的代码:
在模板中
<ng-template [ngIf]="!loading" [ngIfElse]="loadingView">
<router-outlet *ngIf="canView"></router-outlet>
<app-permission-denied *ngIf="!canView"></app-permission-denied>
</ng-template>
<app-loading #loadingView></app-loading>
在组件中
import { Component, OnInit} from '@angular/core';
import {
Router,
// import as RouterEvent to avoid confusion with the DOM Event
Event as RouterEvent,
NavigationStart,
NavigationEnd,
NavigationCancel,
NavigationError
} from '@angular/router'
import { Title } from '@angular/platform-browser';
import { DataService } from '../core/service/data.service';
import { NotificationService } from '../core/service/notification.service';
@Component({
selector: 'app-main',
templateUrl: './main.component.html',
styleUrls: ['./main.component.css']
})
export class MainComponent implements OnInit{
// Sets initial value on first load
loading: boolean = true;
canView: boolean = false;
haveErr: boolean = false;
constructor(private renderer: Renderer2,
private router: Router,
private _dataService: DataService,
private titleService: Title,
private _notificationService: NotificationService) {
this.router.events.subscribe((event: RouterEvent) => {
this.navigationInterceptor(event)
})
}
ngOnInit() { }
navigationInterceptor(event: RouterEvent): void {
if (event instanceof NavigationStart) {
this.loading = true;
this.canView = false;
}
if (event instanceof NavigationEnd) {
//get permission user by pass function ID here...
let functionId = this.getDataRouter(this.router, "function");
if (functionId != null) {
this._dataService.get('your_api_to_check_permission_with_functionId' + functionId).subscribe(
(data) => {
if (data && data.CanRead) {
this.canView = true;
let title = this.getDataRouter(this.router, "title");
this.titleService.setTitle(title);
} else {
this.canView = false;
this.titleService.setTitle('Permission denied');
}
this.loading = false
}, (err) => {
this._dataService.handleError(err);
});
} else {
this.loading = false;
this.canView = true;
this._notificationService.printErrorMessage('Dev: please provide function Id to check permission');
}
}
// Set loading state to false in both of the below events to hide in case a request fails
if (event instanceof NavigationCancel) {
this.loading = false
}
if (event instanceof NavigationError) {
this.loading = false
}
}
getDataRouter(router, name) {
var root = router.routerState.snapshot.root;
while (root) {
if (root.children && root.children.length) {
root = root.children[0];
} else if (root.data && root.data[name]) {
return root.data[name];
} else {
break;
}
}
return null;
}
}
在路由器模块中
const mainRoutes: Routes = [
{ path: 'user', loadChildren: './system/user/user.module#UserModule', data: { function: "USER" } },
{ path: 'function', loadChildren: './system/function/function.module#FunctionModule', data: { function: "FUNCTION" } }
]
答案 3 :(得分:0)