Эквивалент маршрутной охраны для функций компонентов
Мне интересно, есть ли эквивалент для охранников маршрута для функций угловых компонентов (в частности, событий щелчка).
У нас настроена защита маршрута, которая открывает страницу входа, когда вы не вошли в систему. Это прекрасно работает. Проблема в том, что у нас есть компонент, который не требует проверки подлинности для просмотра, но некоторые функции внутри компонента требуют проверки подлинности. Например, список новостных статей, но кнопки 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, чтобы скрыть / показать кнопки голосования в зависимости от того, вошел ли пользователь в систему или нет.