Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 592
Roman Skydan Avatar asked Oct 05 '17 21:10

Roman Skydan


People also ask

How role Based authentication works in Angular?

Understanding role-based authorization with angular We will make an angular app to restrict the access of sources of a page by implementing role-based authorization. This application will contain 3 pages (a login page, a home page, an admin page). In our application, the user can either be a normal user or an admin.

What is permission in angular?

Modern applications usually displays only what is visible to the user based on their role. For example, a guest user may read stories but can't write comments on Medium. Or another example, an authorized user can write and remove drafts.


3 Answers

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.

like image 98
GreyBeardedGeek Avatar answered Sep 24 '22 07:09

GreyBeardedGeek


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.

like image 40
Wesley Coetzee Avatar answered Sep 21 '22 07:09

Wesley Coetzee


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

like image 30
Rahul Singh Avatar answered Sep 21 '22 07:09

Rahul Singh