简体   繁体   中英

How would you manage user roles and permissions using Angular 2

I'm working on a new Angular2 app, and I was wondering how would you manage routes accessible to certain roles and permissions to create, edit, and delete items for certain roles.

I want to know how do you solve the problem such this:

  • How do you manage access to some UI elements? How does the app know to show or hide it? Do you use single service for this? Or do you create different conditions for the different place in your app?

  • How do you manage your routing? Do you use CanActivate, CanActivateChild, CanLoad and etc? Do you build a single guard service for all routes or make different services for different modules or component?

  • And last question. What is the best way to divide the app then you can sell it like a CMS? I mean how can we realize possibility to load some other modules from the market for example, and add it in your app?

How do you solve the similar problem?

Any guidance, experience, or pointers to material covering these topics is greatly appreciated. Thanks in advance.

As mentioned in the comments to your question, a complete answer is beyond the scope of a SO question/answer, and so you may find your question closed in the near future for that reason, but here's some quick suggestions for you to explore further on your own:

  • Get the user's permissions from the server during/after login via http/https. Store these permissions somewhere that makes sense for your app, perhaps in a service. If you're using JWT, the permissions can be returned in the JWT token.

  • To simplify things, only deal with permissions on the client. Roles are for the server code to figure out what permissions the user has. No need to muck things up by conflating roles with permissions on the client.

  • Protect routes with auth guards

  • Protect individual UI elements with *ngIf or ngSwitch/*ngSwitchCase

  • Dynamic Loading is a big topic area - go read about it - lots of resources on the web. However, as far as I know, while you can lazily load modules, they must be known to the application at compile-time. I may be mistaken, but I don't think that you can just load anything you want at runtime.

So I had to implement something like this on an application I worked out, this is how I handled it.

I created a auth service, this contained a method that checked if the user had a management role:

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');
}

I created an auth guard as follows:

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 { }

I then used the guard for my route that handles navigation to the admin section

app-routing.module.ts

{ path: 'management', component: AdminComponent, canActivate: [GuardComponent] }

On my navigation bar I just call the isManager method and stored that on a variable and use that to determine whether or not the management link needs to be displayed or not.

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>

I've had to remove some data from each method, but this will give you the basic idea. Hopefully this helps.

This question is quite broad and i don't thing you can cover it easily in this answer. There are basically three things attached to it

  • Routing
  • Guards
  • Modules

You need to have single guard module that will check for the entire app and all the sub routes will be a children for the guard route . In short it will act like a global guard for your whole application . And Your routing will be covered in short . More on Guards

And now talking about modules you need to split everything into common and featured modules and reuse the modules or use it independently. This will help you sell it like a CMS . More on Modules .

Note - This is not a exact answer but a gist to your problem

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM