簡體   English   中英

在Angular 4中使用權限的最佳方法是什么?

[英]What's the best way to work with permissions in Angular 4?

在我的Angular 4項目中,我想使用權限,我從API獲得。 權限保存為帶有ID的數組。 某些單個元素(如用戶或博客帖子)具有允許權限的屬性,允許或不允許編輯或刪除等操作作為帶有ID的數組。

在Angular 4項目中檢查和處理權限的最佳方法是什么? Angular中有一些用於權限處理的bos解決方案嗎? 如果Angular沒有一些開箱即用的解決方案,有人可以給我實現權限處理的想法嗎?

像Rahul評論說開箱即用的解決方案更可能是你想要的Guard

請記住,警衛只適用於ROUTING ..所以只檢查用戶是否可以訪問路線..但不要根據角色或其他任何內容顯示組件中的單個元素..我建議您使用*ngIf或顯示以呈現/顯示或不顯示某些UI元素...

對於基於角色的一個Guard(不僅如果使用是否是auth)..你可以做類似的事情:

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'] }
          }
        ]
      }

您可以嘗試使用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>

從我個人的角度來看,獲得API的許可是用戶權利的最佳解決方案。 除了在Router中使用canActivate屬性檢查權限之外,我還想使用導航攔截器中的檢查。 因為它會在檢查不正確的權限而不是url localhost:42000 /#/.../ permission-denied時保留url

這是我的代碼:

在模板中

  <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" } }
    ]

我建議你這樣做的最好方法是使用Angular提供的Router Guard

以下鏈接可幫助您入門:

路由器護衛鱷魚

路由器防護中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM