如何使用 Guard 根据 Angular Material 对话框的输入保护 URL?

How can I protect a URL based on the input of an Angular Material Dialog using a Guard?

目标:

我有一个特定的 URL 使用 Guard 进行保护。当用户尝试访问那个 URL 我有一个 Angular 4 material 对话框打开。根据对话框输入,我想授权或不授权用户。

问题:

在 Guard 中我订阅了对话。关闭时我收到对话框输入。当用户尝试访问 URL 时,canActivate 会自动评估为 false,而无需等待用户输入。 换句话说,订阅了modal,但立即返回false,因为函数没有等待对话框关闭。

问题:

如何根据用户输入授权或不授权用户URL?

后卫:

    @Injectable()
    export class VerificationGuard implements CanActivate {

      pwd: string;
      auth: boolean;

      constructor(private dialog: MatDialog) {
      }

      public canActivate() {
        const dialog = this.dialog.open(VerificationDialogComponent);
        dialog.afterClosed()
          .subscribe(val => {
            if (val) {
              this.pwd = val;
              return true;
            }
          });
        return false;
      }
    }

对话:

    import { Component, OnInit } from '@angular/core';
    import { MatDialogRef } from '@angular/material';

    @Component({
      selector: 'app-verification-dialog',
      templateUrl: './verification-dialog.component.html',
      styleUrls: ['./verification-dialog.component.scss']
    })
    export class VerificationDialogComponent implements OnInit {

      pwd: string;

      constructor(public dialogRef: MatDialogRef<VerificationDialogComponent>) { }

      ngOnInit() {
      }

      /**
       * Close dialog and pass back data.
       */
      confirmSelection() {
        this.dialogRef.close(this.pwd);
      }
    }

与其从 VerificationGuard 打开此模式,不如考虑使用服务来存储标志。

@Injectable()
export class AuthService {
  isLoggedIn = false;
}

该服务不会让您登录,但它有一个标志告诉您用户是否已通过身份验证。

从你的守卫中调用它:

@Injectable()
export class VerificationGuard implements CanActivate {

  constructor(private authService: AuthService) {}

  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
    return this.authService.isLoggedIn)
  }
}

将您的模态逻辑重新定位到您的路由器导航事件发出的位置,并让它在提交凭据时执行以下操作:

  1. AuthService.isLoggedIn 设置为 true
  2. 发出路由器导航事件。
  3. 将守卫的AuthService.isLoggedIn设置为false

AuthService.isLoggedIn 应重置为 false,canActivate() 应 return true。

有关类似示例,请参阅 "Teach AuthGuard to authenticate" 下的 https://angular.io/guide/router#canactivatechild-guarding-child-routes