3

我想知道是否有等效于角度组件功能(特别是单击事件)的路由保护。

我们设置了一个路由守卫,在未登录时会打开一个登录页面。这很好用。问题是,我们有一个不需要身份验证即可查看的组件,但组件中的某些功能确实需要身份验证。例如,新闻文章列表,但upvote/downvote 按钮需要身份验证才能使用。

upvote/downvote 按钮只是点击事件触发组件功能。我们可以将我们在自定义路由保护中使用的逻辑添加到这些函数中,但这会导致大量重复代码。

我想知道 Angular 是否有内置的东西可以解决这个问题。我正在考虑类似于 ASP.NET MVC 的 [Authorize] 属性的东西,您可以将其放在操作的顶部进行身份验证。据我所知,路由守卫仅适用于路由,而不适用于点击事件。

4

3 回答 3

6

对于任何对解决方案感兴趣的人,我能够弄清楚如何在一个函数中使用我现有的路由保护。这消除了 if/else 语句的需要,其中 else 语句包含路由保护在未经身份验证时执行的逻辑。似乎是我能找到的最干净的解决方案。

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

upvoteClick(article: NewsArticle): void {

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

于 2017-11-03T16:18:09.693 回答
0

我找到了另一种实现动作防护的方法。它是拦截器。当操作在没有有效令牌或没有必要数据的情况下向服务器发送请求时,服务器返回 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);
      }));

  }
}
于 2020-07-05T12:53:41.290 回答
-1

如果您的用户已登录,您的路由守卫如何测试?希望您已经设置了一个授权服务来检查它并将其注入您的警卫。如果是这样,请将其注入您的投票组件并简单地使用 *ngIf 根据用户是否登录来隐藏/显示投票按钮。

于 2017-11-02T23:48:47.173 回答