我已经在Angular 4中设置了两个警卫 - 一个用户在尝试访问受保护的路由时将用户重定向到登录页面,另一个用户将用户重定向到“Home”的欢迎页面(如果他们还没有还有。
守卫本身工作得很漂亮......但我注意到一些非常奇怪的行为。通过WelcomeTraveler防护中的this.router.navigate
添加重定向会使应用程序处于无法从第一个防护中访问受保护路由的状态,即使在登录后也是如此。我只是不断收到回复到主页。
以下是我的警卫:
export class AuthGuardLoggedInUser implements CanActivate {
private isLoggedIn: boolean;
private working: boolean;
constructor (@Inject(Store) private _store:Store<AppStore>, @Inject(Router) private _router: Router)
{
_store.select(state => state.AuthNState).subscribe(auth =>
{
this.isLoggedIn = auth.connected
this.working = auth.working
})
}
canActivate() {
if (this.working)
{
let promise: Promise<boolean> = new Promise((resolve, reject) => {
let sub = this._store.select(state => state.AuthNState).subscribe(auth =>
{
if (!auth.working) {
resolve(auth.connected)
sub.unsubscribe()
if (!auth.connected) this._router.navigate(['/i/login']);
}
})
});
return promise
}
else if (this.isLoggedIn){
return true
}
else {
this._router.navigate(['/i/login']);
}
export class WelcomeTraveler implements CanActivate {
private hasAlreadyVisitedWelcomePage: boolean;
private isLoggedIn: boolean;
private working: boolean;
constructor (@Inject(Store) private _store:Store<AppStore>, @Inject(Router) private _router: Router)
{
_store.select(state => state.AuthNState).subscribe(auth =>
{
this.isLoggedIn = auth.connected
this.working = auth.working
})
}
canActivate() {
if (this.working)
{
let promise: Promise<boolean> = new Promise((resolve, reject) => {
let sub = this._store.select(state => state.AuthNState).subscribe(auth =>
{
if (!auth.working) {
resolve(auth.connected)
sub.unsubscribe()
this.hasAlreadyVisitedWelcomePage = true
this._router.navigate(['/i/welcome']);
}
})
});
return promise
}
else if (this.isLoggedIn){
return true
}
else if (!this.hasAlreadyVisitedWelcomePage){
this.hasAlreadyVisitedWelcomePage = true
this._router.navigate(['/i/welcome']);
}
else return true
}
}
这是路由表的一小部分:
export var AppRoutes = RouterModule.forRoot([
{
path: '',
component: HomeComponent,
canActivate: [WelcomeTraveler]
}, {
path: 'i/getstarted',
component: GetStartedPageComponent,
canActivate: [AuthGuardLoggedInUser]
}, {
path: 'i/login',
component: LoginPageComponent
}, {
path: 'i/profile',
component: ProfilePageComponent,
canActivate: [AuthGuardLoggedInUser]
}, {
path: 'i/welcome',
component: WelcomePageComponent
}])
this.router.navigate
后卫中WelcomeTraveler
的存在似乎会导致问题,即使这些线路从未被击中!登录后,我会在尝试路由到配置文件后立即回到“主页”(成功通过第一个警卫后)。如果我删除导航线 - 问题就会消失。
有什么想法吗?
答案 0 :(得分:2)
经常发生这种情况,我在这里走错了路。对于那些可能已经加星标或更多选票的人,我建议你检查一下调用router.navigate
的任何订阅 - 在我的情况下,我在登录/注册时未能清理这些订阅组件...所以一旦订阅被初始化,任何时候状态更新我被重定向到主页。
修正如下:
export class LoginPageComponent implements OnDestroy {
private _redirectSubscription: Subscription;
constructor (private _store:Store<AppStore>, private router: Router) {
this._redirectSubscription = _store.select((state) => state.AuthNState).subscribe((auth) =>
{
if (auth.connected) this.router.navigate(['']);
})
}
ngOnDestroy() {
//Called once, before the instance is destroyed.
//Add 'implements OnDestroy' to the class.
this._redirectSubscription.unsubscribe();
}
}