Angular 即使路由器导航到不受保护的元素 2,路由器也会调用元素 1 的 canActivate
Angular router calls canActivate of element 1 even if router navigates to unguarded element 2
我有两个组件:HomeComponent
由 AuthGuard 保护,LoginComponent
没有任何保护。
当我从 HomeComponent
调用 logout()
时,我从 localStorage
销毁令牌并调用 this.router.navigate(['/login'])
。这会在一瞬间将我重定向到 LoginComponent
;然后我的应用程序就像我试图直接调用 HomeComponent
并因此再次调用 canActivate()
函数一样,这导致应用程序完全重新加载。
以下是我的部分代码:
注销功能
logout() {
// remove user from local storage to log user out
localStorage.removeItem('currentUser');
this.router.navigate(['/login']);
this.currentUserSubject.next(null);
}
app.routing.ts
{ path: 'login', component: LoginComponent },
{ path: '', component: HomeComponent, canActivate: [AuthGuard] },
我的 AuthGuard canActivate()
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const currentUser = this.authenticationService.currentUserValue;
if (currentUser) {
// authorised so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
return false;
}
我希望应用程序不会重新加载,它只会转到 /login
。我怎样才能做到这一点?
编辑 1
我尝试在 stackblitz here 中创建我的应用程序的迷你版本。我是 Angular 的新手,因此在那里重现问题时我没有遇到什么问题。
单击演示中的登录按钮后,会创建一个 localStorage 项,但路由器不会导航到 /
。请您从浏览器 URL 中删除 /login...
部分,然后按回车键重新加载页面。您将看到该应用程序的行为方式。
尝试注销并查看问题。
我猜你有一个 this.currentUserSubject.next(null);
的订阅者,它加载了你的 HomePage
。这当然指向 /login
。一种解决方案是检查订阅者中的 null
。
重新加载是因为您正在使用
<a href="" ...>
注销。这告诉浏览器导航到当前 URL(即重新加载页面)。
您应该使用按钮,而不是 link。如果您使用 link,至少要防止 link:
的默认操作
(click)="logout($event)"
logout(event: Event) {
// ...
event.preventDefault();
}
我有两个组件:HomeComponent
由 AuthGuard 保护,LoginComponent
没有任何保护。
当我从 HomeComponent
调用 logout()
时,我从 localStorage
销毁令牌并调用 this.router.navigate(['/login'])
。这会在一瞬间将我重定向到 LoginComponent
;然后我的应用程序就像我试图直接调用 HomeComponent
并因此再次调用 canActivate()
函数一样,这导致应用程序完全重新加载。
以下是我的部分代码:
注销功能
logout() {
// remove user from local storage to log user out
localStorage.removeItem('currentUser');
this.router.navigate(['/login']);
this.currentUserSubject.next(null);
}
app.routing.ts
{ path: 'login', component: LoginComponent },
{ path: '', component: HomeComponent, canActivate: [AuthGuard] },
我的 AuthGuard canActivate()
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
const currentUser = this.authenticationService.currentUserValue;
if (currentUser) {
// authorised so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
return false;
}
我希望应用程序不会重新加载,它只会转到 /login
。我怎样才能做到这一点?
编辑 1
我尝试在 stackblitz here 中创建我的应用程序的迷你版本。我是 Angular 的新手,因此在那里重现问题时我没有遇到什么问题。
单击演示中的登录按钮后,会创建一个 localStorage 项,但路由器不会导航到 /
。请您从浏览器 URL 中删除 /login...
部分,然后按回车键重新加载页面。您将看到该应用程序的行为方式。
尝试注销并查看问题。
我猜你有一个 this.currentUserSubject.next(null);
的订阅者,它加载了你的 HomePage
。这当然指向 /login
。一种解决方案是检查订阅者中的 null
。
重新加载是因为您正在使用
<a href="" ...>
注销。这告诉浏览器导航到当前 URL(即重新加载页面)。
您应该使用按钮,而不是 link。如果您使用 link,至少要防止 link:
的默认操作(click)="logout($event)"
logout(event: Event) {
// ...
event.preventDefault();
}