Angular Guards — это механизмы, которые позволяют вам контролировать доступ к определенным маршрутам в вашем приложении Angular.

Они используются для защиты маршрутов в зависимости от конкретных условий и выполняются перед активацией маршрута.

Angular предоставляет несколько типов защиты:

  1. CanActivate: этот сторожевой элемент используется для определения того, можно ли активировать маршрут и получить к нему доступ. Он проверяет, разрешено ли пользователю переходить по определенному маршруту на основе определенных условий, таких как статус проверки подлинности, роль пользователя или любая пользовательская логика. Если сторож CanActivate возвращает true, маршрут доступен; в противном случае, если он возвращает объект false или UrlTree, навигация блокируется, и пользователь перенаправляется на другой маршрут.
  2. CanActivateChild. Аналогично CanActivate, но применяется к дочерним маршрутам. Он используется для управления доступом к дочерним маршрутам определенного родительского маршрута.
  3. CanDeactivate: этот сторожевой элемент используется, чтобы определить, может ли пользователь уйти с маршрута. Он проверяет, может ли пользователь безопасно покинуть текущий маршрут, возможно, предлагая ему диалоговое окно подтверждения, если есть несохраненные изменения или незавершенные действия.
  4. CanLoad. Эта защита используется при реализации модулей с отложенной загрузкой. Он определяет, можно ли загрузить модуль с отложенной загрузкой на основе определенных условий, таких как статус аутентификации или роли пользователей.
  5. Resolve: Resolve guard используется для получения необходимых данных для маршрута до того, как маршрут будет активирован. Он ожидает, пока данные будут разрешены, прежде чем продолжить активацию маршрута, гарантируя, что необходимые данные будут доступны при инициализации компонента.
// guards/user.guard.ts

import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router } from '@angular/router';

@Injectable()
export class UserGuardService implements CanActivate {
  token: string | null = '';
  role: string | null = '';

  constructor(private router: Router) {}

  canActivate(route: ActivatedRouteSnapshot): boolean {
    this.token = localStorage.getItem('token');
    this.role = localStorage.getItem('RoleType');

    if (this.token == null) {
      this.router.navigate(['/login']);
      return false;
    }
    if (this.token !== null && this.role === 'Admin') {
      this.router.navigate(['/admindashboard']);
      return false;
    }
    if (this.token !== null && this.role === 'User') {
      this.router.navigate(['/userdashboard']);
      return false;
    }

    return true; // Allow the route to be activated if none of the previous conditions match
  }
}

ПРИМЕЧАНИЕ. краткое объяснение того, когда следует возвращать true или false в методе canActivate:

  1. Возврат true: если охранник вернет true, это позволит активировать маршрут, и навигация продолжится как обычно.
  2. Возврат false: если сторож возвращает false, это предотвращает активацию маршрута, и навигация будет остановлена ​​или перенаправлена ​​на основе логики сторожа.

Когда возвращать false:

  • Если у пользователя нет необходимых учетных данных или авторизации для доступа к определенному маршруту, вы можете вернуть false, чтобы запретить ему доступ к этому маршруту. В этом случае вы можете перенаправить пользователя на страницу входа или другую подходящую страницу.
  • Если пользователь уже прошел аутентификацию и вы хотите перенаправить его на другую страницу в зависимости от его роли или какого-либо другого условия, вы можете вернуть false и использовать метод Router.navigate() для перенаправления на нужную страницу.

Когда возвращать true:

  • Если у пользователя есть необходимые учетные данные или полномочия для доступа к определенному маршруту, вы должны вернуть true, чтобы разрешить активацию маршрута, и навигация продолжится как обычно.
  • Если у охраны нет каких-либо конкретных условий для проверки или ограничений, и вы просто хотите разрешить безоговорочную активацию маршрута, вы можете вернуть true.
// app-routing.module.ts


const routes: Routes = [
  { path: 'login', loadChildren: () => import('./login/login.module').then(m => m.LoginModule) },
  { path: 'signup', loadChildren: () => import('./signup/signup.module').then(m => m.SignupModule) },
  {
    path: 'admindashboard',
    loadChildren: () => import('./admin-dashboard/admin-dashboard.module').then(m => m.AdminDashboardModule),
    canActivate: [UserGuardService], // Apply UserGuardService for AdminDashboard route
    data: { expectedRole: 'Admin' }, // You can pass additional data like the expected role
  },
  {
    path: 'userdashboard',
    loadChildren: () => import('./user-dashboard/user-dashboard.module').then(m => m.UserDashboardModule),
    canActivate: [UserGuardService], // Apply UserGuardService for UserDashboard route
    data: { expectedRole: 'User' }, // You can pass additional data like the expected role
  },
  { path: '', redirectTo: '/login', pathMatch: 'full' }, // Redirect to login by default
  { path: '**', redirectTo: '/login', pathMatch: 'full' }, // Redirect to login for any other unknown route
];

@NgModule({
  imports: [
    RouterModule.forRoot(routes),
    LoginModule,
    SignupModule,
    AdminDashboardModule,
    UserDashboardModule,
  ],
  exports: [RouterModule],
})
export class AppRoutingModule {}

В приведенном выше AppRoutingModule, который определяет конфигурацию маршрутизации для нашего приложения Angular. Он использует ленивую загрузку функциональных модулей, то есть метод загрузки модулей только тогда, когда они необходимы, что сокращает время первоначальной загрузки нашего приложения.

Свойство loadChildren используется для отложенной загрузки. Когда пользователь переходит к маршруту, определенному с помощью loadChildren, указанный модуль загружается по запросу, а не связывается с основным приложением.

Спасибо за чтение! Следуйте за мной на Medium, чтобы получать больше полезных статей. Если у вас есть какие-либо вопросы, оставьте их в разделе комментариев!

Удачного кодирования!!