Мое приложение имеет панель навигации с некоторыми ссылками на различные компоненты. Эти кнопки должны быть видны, только если пользователь вошел в систему, и пользователь подтвердил свою электронную почту. Маршруты к компонентам также защищены 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]
из модуля app-routing кнопки навигации работают в обычном режиме.
3) Если я изменю условие * ngIf в ссылках Компонент 1 и Компонент 2, чтобы оно соответствовало ссылке Выход, т. е. *nfIf="authService.authState | async"
, то кнопки будут работать, и защитные устройства будут работать.
Так что я не могу понять, где я ошибся. Кажется, что-то связано с использованием afAuth.user в * ngIf, но я действительно не знаю, почему.
РЕДАКТИРОВАТЬ: нет ошибок консоли
РЕДАКТИРОВАТЬ: маршрутизация в Дочерние компоненты выглядят следующим образом:
component-1-routing.module.ts
...
const routes: Routes = [{ path: '', component: ComponentOneHomeComponent }];
...
component-2-routing.module.ts
...
const routes: Routes = [
{
path: "",
component: ComponentTwoHomeComponent,
children: [
{ path: "", redirectTo: "component-2" },
{ path: "child-1", component: ChildOneComponent },
{ path: "child-2", component: ChildTwoComponent },
{ path: "child-3", component: ChildThreeComponent }
]
}
];
...