目标:
我有一个使用防护保护的特定 URL。当用户尝试访问该 URL 时,我会打开一个 Angular 4 材料对话框。根据对话框输入,我想授权或不授权用户。
问题:
在警卫中,我订阅了该对话框。关闭时,我收到对话框输入。当用户尝试访问 URL 时,canActivate 会自动评估为 false,而无需等待用户输入。 换句话说,模式被订阅,但会立即返回 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)
}
}
将模式逻辑重新定位到发出路由器导航事件的位置,并让它在提交凭据时执行以下操作:
- 将
AuthService.isLoggedIn
设置为true
。 - 发出路由器导航事件。
- 将
AuthService.isLoggedIn
设置为从防护装置中false
。
AuthService.isLoggedIn
应重置为 false,canActivate()
应返回 true。
有关类似示例,请参阅"教 AuthGuard 进行身份验证"下的 https://angular.io/guide/router#canactivatechild-guarding-child-routes。