What is the role of authguard in securing routes?

When developing an application, I encountered the need to implement authorization to protect routes using AuthGuard. However, I now face the challenge of securing child routes based on a role system obtained from the backend during login. For example, if the user's role is 'admin,' they should have access to all routes; if the role is 'user,' they should only be able to access the 'notification' route. I attempted to use *ngIf, but it only hides the route and does not prevent users from accessing it via the URL.

auth.guard.ts

  // Implementing the canActivate method with AuthService logic for authentication
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    const isAuth = this.authService.getIsAuth();
    if (!isAuth) {
      this.router.navigate(['/sign-in']);
    }
    return isAuth;
  }

roleAuth.guard.ts

  // Implementation of canActivate for role-based authorization
  canActivate(
    next: ActivatedRouteSnapshot,
    state: RouterStateSnapshot): Observable<boolean | UrlTree> | Promise<boolean | UrlTree> | boolean | UrlTree {

    const role = this.authService.role();
    if (role ==='Admin') {
     // Stuck at handling admin authorization
    }
   if (role ==='moderator') {
     // Stuck at moderator authorization
    }
   if (role ==='user') {
     // Stuck at user authorization
    }
    return role;
  }

app-routing.ts

// Setting up the routes with AuthGuard protection and children routes configuration
const routes: Routes = [
  { path: 'sign-in', component: SignInComponent },
  {
    path: '',
    canActivate: [AuthGuard],
    component: SideNavComponent,
    children: [
      { path: '', redirectTo: '/dashboard', pathMatch: 'full' },

      {
        path: 'dashboard',
        loadChildren: () => import('./components/sidenav/pages/dashboard/dashboard.module')
          .then(m => m.DashboardModule)
      },
      {
        path: 'notifications',
        loadChildren: () => import('./components/sidenav/pages/notifications/notifications.module')
          .then(m => m.NotificationsModule)
      },

    ],
  },

];

Answer №1

To protect the dashboard route, you should implement a RoleAdminGuard with the canActivate and canLoad methods. Here's an example:

role-admin.guard.ts

canLoad(route: Route, segments: UrlSegment[]): Observable<boolean>|Promise<boolean>|boolean {
    const isAdmin = this.authService.getAuth().role === 'ADMIN';
    if (isAdmin) {
      this.router.navigate(['/notifications']);
    }
    return isAdmin;
}

app-routing.module.ts

const routes: Routes = [
  { path: 'sign-in', component: SignInComponent },
  {
    path: '',
    canActivate: [AuthGuard],
    component: SideNavComponent,
    children: [
      { path: '', redirectTo: '/dashboard', pathMatch: 'full' },

      {
        path: 'dashboard',
        canLoad: [RoleAdminGuard],
        loadChildren: () => import('./components/sidenav/pages/dashboard/dashboard.module')
          .then(m => m.DashboardModule)
      },
      {
        path: 'notifications',
        loadChildren: () => import('./components/sidenav/pages/notifications/notifications.module')
          .then(m => m.NotificationsModule)
      },

    ],
  },

];

Answer №2

If you find yourself in a situation where child level route restrictions are necessary, consider implementing a feature module architecture for your project. Check out the Angular Guide on feature modules for more information. Once you've made this structural change, you can easily apply an [Authguard] to the child routes within your feature module routing.

const routes: Routes = [
    {
        path: '',
        component: ClientDashboardComponent
    },
    {
        path: 'edit/:id',
        component: ClientEditComponent,
        canActivateChild: [AuthorizeGuard],
        data: { roles: [PermissionCodes.ClientProfile_Write] },
        canDeactivate: [CanDeactivateGuard]
    } ]

By following this example, you can restrict access to your child routes even if users attempt to enter the URL in a new tab. Hopefully, this solution proves helpful for your specific scenario.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

With Crypto-JS, a fresh hash is always generated

I'm looking to integrate crypto-js into my Angular 8 application. Here is a snippet of my code: import {Injectable} from '@angular/core'; import * as CryptoJS from 'crypto-js'; @Injectable() export class HprotoService { public ...

The binding to 'videoId' cannot be established as it is not a recognized attribute of the 'youtube-player' component

Currently, I am working with Ionic 3 and Angular 5. In my application, I am integrating Youtube videos using ngx-youtube-player. However, I am encountering errors: Template parse errors: Can't bind to 'videoId' since it isn't a know ...

styled components are having issues with background gradients and opacity not functioning properly

Hello, I am currently working with styled components and have the following global style code: const GlobalStyle = createGlobalStyle` html{ font-family: roboto; background: linear-gradient(45deg,rgba(137,255,255,0.5),rgba(161,252,143, 0 ...

Is there a way I can keep my ChartJS constantly updated in real time? Currently, it only seems to update when I zoom in or out

I'm looking to create a dynamic graph that updates every 5 seconds or in real-time. I've managed to get it working when zooming in and out of the page, but not when doing nothing. I know it's possible to achieve this, but I can't seem t ...

What is the proper way to include special symbols such as "++" and "#" in a request?

I am facing an issue while trying to make a request to an ASP .NET CORE API from an Angular application using Typescript. Upon sending the request, the API searches in an SQL database for any rows with the specified value. The problem arises when attempt ...

The service is sending back an object and ngFor is having trouble accepting data in object format

I am currently developing an Angular Application in which I am attempting to display some information in the DOM. However, I am encountering an error with ngFor not accepting object format data. My goal is to iterate over the data. The error message rea ...

Is there a TypeScript type that represents a subset of the keys of another type?

When given an object, is it possible to create a second typed object that contains only a subset of the original keys with different value types? I attempted to use Partial<keyof ...>, but it did not have the desired effect. Is there another approach ...

Arrange elements both at the beginning and the end of a line using FlexLayout in Angular

Using the Angular flexlayout library in angular 7/8, I am trying to align 4 buttons on the left side (flex-start) and two checkboxes on the right side (flex-end) at the same level. I would prefer to achieve this layout using the flexlayout Angular library. ...

Determine the point where a cube intersects a plane using Three.js

Given a plane and a cube, I am interested in determining if they intersect. If they do intersect, I would also like to find out: What shape does their intersection form - a triangle, a parallelogram or a hexagon? In degenerate cases, it may just be a p ...

A guide to simulating ngControl in a Custom Form Control for effective unit testing in Angular

I need some guidance on creating unit tests for a Custom Form Control in Angular 9. The issue arises with this line of code: constructor(@Self() private ngControl: NgControl), which triggers an error: Error: NodeInjector: NOT_FOUND [NgControl]. It seems th ...

The conundrum of Content-Type in Angular 8's HttpClient Post request

Seeking assistance with POST request to backend API! I'm encountering a 415 status code due to the content-type being sent as "text/plain" when the endpoint expects application/json. Interestingly, the POST works in PostMan (see screenshot below). I ...

Looking for guidance on implementing explicit waits in Protractor for non-angular applications

I have noticed that automating non-angular applications with Protractor can be challenging. Currently, I am using some methods to add an explicit wait to my existing Serenity click and enter functions. However, I am curious if there is a way to automatic ...

Using ngFor directive to iterate through nested objects in Angular

Receiving data from the server: { "12312412": { "id": "12312412", "something": { "54332": { "id": "54332", "nextNode": { "65474&q ...

The TLS connection could not be established as the client network socket disconnected prematurely

While attempting to run npm install on an Angular 5 dotnetcore project that I pulled down from source tree, everything was running smoothly on my work machine. However, when I tried to do the initial npm install on my home machine, I encountered the foll ...

Why does the private map function in the class fail while the global function succeeds?

Issues arise when calling the map() function on a parsed JSON object within the mapStocks() function. Placing the toStock() function inside the StockService class results in failure, whereas declaring it as a "global" function outside the class works witho ...

An issue has occurred with ng-material-multilevel-menu: NullInjectorError - MultilevelMenuService provider is missing. This problem is specific to

I have been working with Angular 12 and I am looking to integrate the ng-material-multilevel-menu plugin. Following this link, I tried implementing the multilevel menu. Although it compiled successfully, I encountered an error in the browser. After some ...

Navigating through a mergeMap observable with an undefined value

In my Angular 6 app, I have a class that attaches API tokens to every http request using the getIdToken() method. If the token retrieval is successful, everything works fine. However, if it fails, my app will stop functioning. I need help with handling th ...

Is it possible to perform sorting and searching of data directly on the client side using AG-Grid?

We have set up an API in .NET Core C# to retrieve data and display it in a grid using AG Grid in Angular. Our API incorporates server-side pagination for efficient data loading. Next, I am looking to add client-side sorting and searching functionalities t ...

Adding a fresh attribute to MongoDB using push model

I wrote a basic script that calculates the number of documents for a specific user and assigns it to externalUser.totalIcons. However, when I try to execute it, the model is not saved and the new property is not added to the database. My question is: wher ...

Making the Angular 2 Http Service Injectable

I am fetching a large object from my server using an Angular 2 service when the website loads. The structure of the data I need to fetch is as follows: { Edu: [...], Exp: [...], Links: [...], Portfolio: [...], Skills: [...] } Here&apo ...