我正在使用NgRx
存储进行身份验证,我的问题在于路由及其子级。我正在使用的防护是用于角色身份验证,同时我通过调度IsAuthenticated
操作检查用户是否仍在服务器上进行身份验证。
当我访问子路线时,问题开始,警卫两次开火,一次为父母,另一次为孩子!如何避免此重复操作调度?我尝试了.take(1)
,但它允许动作只被触发一次,然后完全被忽略。
这是我的警卫服务代码的快照,
@Injectable()
export class RoleGuardService implements CanActivate {
constructor(private store: Store<fromApp.AppState>, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean {
this.store.dispatch(new authActions.IsAuthenticated(fromAuth.authId));
let isInRole = false;
let isAuth: boolean;
let userDashboardUrl: string;
let userRoles: string[];
this.store.select(c => c.auth.entities[fromAuth.authId]).subscribe(
(data: Auth) => {
isAuth = data.authenticated;
userRoles = data.userData.roles;
userDashboardUrl = data.userData.dashboardUrl;
});
const expectedRole: Array<string> = (route.data.expectedRole['roles']).map(
(roles) => {
return roles.toUpperCase();
}
);
if (userRoles) {
userRoles = (userRoles).map(
(data) => {
return data.toUpperCase().substring(0, data.length - 1);
}
);
isInRole = expectedRole.some(r => userRoles.indexOf(r) !== -1);
} else {
isInRole = false;
};
if (! isAuth) {
this.store.dispatch(new authActions.Logout(fromAuth.authId, fromAuth.invalidAuth, state.url));
}
if ( isAuth && ! isInRole ) {
this.router.navigate([userDashboardUrl]); // redirect to user dashboard
}
return isInRole;
}
}
我的父路线,
const dbRoutes: Routes = [
{
path: '', component: DbHomeComponent, data: { preload: true }, children: [
{
path: 'registry',
canActivate: [RoleGuardService],
data: { expectedRole: { roles: ['reg'] } },
loadChildren: 'app/core/database/database-cores/registry-core/modules/registry.module#RegistryModule',
}, .....
然后是子路线,
const routes: Routes = [
{ path: '', component: RegistryOutletComponent, children: [
{path: '', component: DashboardComponent},
{
path: 'patientregistration',
component: PatientRegistrationFormComponent,
canActivate: [RoleGuardService],
data: { expectedRole: { roles: ['reg5','reg4'] } },
},
]},
];
和我的副作用,
@Effect()
onIsAuthenticatedUser = this.actions$
.ofType(AuthActions.ISAUTHENTICATED)
.map((action: AuthActions.IsAuthenticated) => { return action })
.switchMap((action: AuthActions.IsAuthenticated) => {
const actionPayload = action;
return this.httpService.getRequest('Account/IsAuthenticated')
.catch(() => { return Observable.empty() })
.switchMap((isAuth: HttpResponse<boolean>) => {
if (!isAuth.body) {
return Observable.of(new AuthActions.Logout(fromAuth.authId, fromAuth.invalidAuth, actionPayload.returnUrl));
} else {
return Observable.concat(
Observable.of(new AuthActions.Authenticated(fromAuth.authId, this.fetchUserData()),
),
Observable.empty());
}
});
});
这里我注意到了这个问题,