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

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

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

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

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


person adam3039    schedule 02.11.2017    source источник
comment
Нет ничего лучше охранников для функций, но я полагаю, что у вас есть какой-то auth.service, и вы можете проверить authService.isAuthorized() по щелчку. Другим способом защиты здесь будет полное скрытие этих кнопок из DOM с помощью *ngIf, снова ссылающегося на какое-то логическое значение в вашем компоненте, которое вы можете установить в ngOnInit. Если вам нужно динамически отслеживать isAuthorized, вы можете поместить эмиттер события или тему в свой authService, который будет распространять изменения и подписываться на него.   -  person Vitalii Chmovzh    schedule 03.11.2017


Ответы (3)


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

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

upvoteClick(article: NewsArticle): void {

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

person adam3039    schedule 03.11.2017

Я нашел другой способ реализовать охрану действий. Это перехватчик. Когда действие отправляет запрос на сервер без действительного токена или без необходимых данных, сервер возвращает 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);
      }));

  }
}
person Anton Valintsev    schedule 05.07.2020

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

person yanbu    schedule 02.11.2017
comment
Да, у меня есть сервис, который я могу ввести, чтобы определить, аутентифицирован ли пользователь (тот же самый, который я использую в защите маршрута). Я предполагаю, что моя проблема в том, что я не хочу скрывать кнопки, я хочу, чтобы они по-прежнему входили в функцию прослушивания кликов, но запрашивали окно входа в систему, если они не аутентифицированы. Я могу сделать все это, но я надеялся, что будет способ избежать использования оператора if/else в каждой функции, которую я хочу аутентифицировать с помощью else, содержащего перенаправления в окно входа в систему. Но если это то, что мне нужно сделать, то это то, что мне нужно сделать! - person adam3039; 03.11.2017