Эквивалент маршрутной охраны для функций компонентов

Мне интересно, есть ли эквивалент для охранников маршрута для функций угловых компонентов (в частности, событий щелчка).

У нас настроена защита маршрута, которая открывает страницу входа, когда вы не вошли в систему. Это прекрасно работает. Проблема в том, что у нас есть компонент, который не требует проверки подлинности для просмотра, но некоторые функции внутри компонента требуют проверки подлинности. Например, список новостных статей, но кнопки upvote / downvote требуют использования аутентификации.

Кнопки upvote / downvote - просто события щелчка, запускающие функции компонентов. Мы можем взять логику, которую мы используем в нашей собственной защите маршрута, и добавить ее к этим функциям, но это приводит к появлению довольно большого количества дублирующегося кода.

Мне было интересно, есть ли в Angular что-то, что может решить эту проблему. Я думаю о чем-то похожем на атрибут [Authorize] ASP.NET MVC, который вы можете поставить в верхней части действия для аутентификации. Насколько я могу судить, охранники маршрута работают только для маршрутов, а не для событий кликов.

2 ответа

Для тех, кто заинтересован в решении, я смог выяснить, как использовать мою существующую систему защиты маршрута в функции. Это исключило необходимость в операторе if/else, где оператор else включал логику, которую выполнял охранник маршрута в случае неаутентификации. Кажется, это самое чистое решение, которое я мог найти.

constructor(private authGuard: AuthGuard, private route: ActivatedRoute){}

upvoteClick(article: NewsArticle): void {

    if (this.authGuard.canActivate(this.route.snapshot)) {
        //logic requiring authentication
    } 
    
}

Я нашел другой способ реализовать экшн-гард. Это перехватчик. Когда действие отправляет запрос на сервер без действительного токена или без необходимых данных, сервер возвращает 401 или 403, в зависимости от вашей настройки

@Injectable()
export class HttpAuthInterceptor {
  constructor(
    private toasterService: ToasterService,
    private auth: AuthService,
    private dialog: MatDialog) { }

  public intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {

    request = request.clone({
      setHeaders: {
        'Authorization': `Bearer ${this.auth.token}`
      }
    });

    return next.handle(request)
      .pipe(catchError(error => {
        if (error instanceof HttpErrorResponse) {
          switch (error.status) {
            case 401:
              this.auth.logout(request.urlWithParams);
              this.dialog.closeAll();
              break;
            case 403:
              this.dialog.closeAll();

              this.dialog.open(ConfirmDialogComponent, {
              
                autoFocus: false,
                width: '65rem',
                maxHeight: '95vh',
                maxWidth: '80vw',
                panelClass: 'confirme__dialog',
                data: {
                  title: 'CONFIRM_DIALOG.TITLE',
                  text: 'CONFIRM_DIALOG.TEXT',
                  onConfirm: () => {
                    this.auth.logout(request.urlWithParams)
                  }
                }
              });

              break;
            case 0:
              this.toasterService.error(error.message, {
                duration: 5000,
              });
              break;
            default:
              this.toasterService.error(error.error.Message, {
                duration: 5000,
              });
          }
        }

        return throwError(error);
      }));

  }
}

Как проходит проверка вашего маршрута, если ваш пользователь вошел в систему? Надеюсь, вы создали службу авторизации, которая проверяет это и вводит ее в вашу защиту. Если это так, вставьте его в свой компонент голосования и просто используйте * ngIf, чтобы скрыть / показать кнопки голосования в зависимости от того, вошел ли пользователь в систему или нет.

Другие вопросы по тегам