我的应用程序有一个导航栏,其中包含一些指向不同组件的链接。仅当用户登录并且用户已验证其电子邮件时,这些按钮才应该可见。到组件的路由也受到Auth Guard的保护。
这是我的代码:
nav.component.html
...
<a
*ngIf="(authService.fbUser$ | async)?.emailVerified"
mat-button
routerLink="component-1"
>Component 1</a>
<a
*ngIf="(authService.fbUser$ | async)?.emailVerified"
mat-button
routerLink="component-2"
>Component 2</a>
<a
*ngIf="!(authService.authState | async)"
mat-button
routerLink="login"
>Sign in</a
>
<button
*ngIf="authService.authState | async"
mat-button
(click)="signOut()"
>
Sign out
</button>
...
auth.service.ts
...
export class AuthService {
fbUser$: Observable<firebase.User | null>;
constructor(private afAuth: AngularFireAuth, private afs: AngularFirestore) {
this.fbUser$ = this.afAuth.user;
}
get authState() {
return this.afAuth.authState;
}
...
verified-user-guard.ts
...
export class VerifiedUserGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
return this.authService.fbUser$.pipe(
take(1),
map(user => (user && user.emailVerified)),
tap(isVerified => {
if (!isVerified) {
this.router.navigate(['email-verification-pending']);
}
console.log(`Verified user: ${isVerified}`);
})
);
}
}
app-routing.module.ts
...
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{
path: 'component-1',
loadChildren: () =>
import('./component-1/component-1.module').then(m => m.ComponentOneModule),
canActivate: [VerifiedUserGuard]
},
{
path: 'component-2',
loadChildren: () =>
import('./component-2/component-2.module').then(m => m.ComponentTwoModule),
canActivate: [VerifiedUserGuard]
}
];
@NgModule({
imports: [RouterModule.forRoot(routes), AuthModule],
providers: [VerifiedUserGuard],
exports: [RouterModule]
})
export class AppRoutingModule {}
...
编辑:单击组件1或组件2链接时,什么也没有发生。页面保持不变。
我已经使用了几天,这就是我发现的内容:
1)身份验证防护装置正在工作,因为如果未验证用户,并且他们尝试通过地址栏访问路由,则会将其重定向到电子邮件验证待处理页面。
2)如果我删除了身份验证防护,即从应用程序路由模块中将canActivate: [VerifiedUserGuard]
注释掉,则导航按钮将正常工作。
3)如果我更改组件1和组件2链接上的* ngIf条件以匹配注销链接(即*nfIf="authService.authState | async"
),则按钮起作用,而auth防护起作用。
所以我无法弄清楚哪里出了问题。这似乎与在* ngIf中使用afAuth.user有关,但我真的不知道为什么。
编辑:没有控制台错误
看起来您好像缺少从true
返回canActivate()
:
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
):
| Observable<boolean | UrlTree>
| Promise<boolean | UrlTree>
| boolean
| UrlTree {
return this.authService.fbUser$.pipe(
take(1),
map(user => (user && user.emailVerified)),
tap(isVerified => {
if (!isVerified) {
this.router.navigate(['email-verification-pending']);
}
return true; // missing this?
console.log(`Verified user: ${isVerified}`);
})
);
}