1

Goal:

I have a specific URL protected using a Guard. When a user attempts to access that URL I have an Angular 4 material dialog open. Based on the dialog input, I want to authorize or not authorize the user.

Issue:

In the Guard I subscribe to the dialog. On close I receive the dialog input. When the user attempts to access the URL, canActivate is automatically evaluated to false without waiting for user input. In other words, the modal is subscribed to, but false is returned immediately because the function does not wait for the dialog to close.

Question:

How can I authorize or not authorize a user to a URL based on user input?

Guard:

    @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;
      }
    }

Dialog:

    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);
      }
    }
4

1 回答 1

1

考虑使用服务来存储标志,而不是从 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.isLoggedIntrue
  2. 发出路由器导航事件。
  3. 设置AuthService.isLoggedInfalse从守卫。

AuthService.isLoggedIn应重置为 false 并canActivate()返回 true。

有关类似示例,请参阅“教 AuthGuard 进行身份验证”下的https://angular.io/guide/router#canactivatechild-guarding-child-routes 。

于 2017-12-11T04:42:14.047 回答