I've got CanActivate guards on all my routes and they are failing over.
For instance, I have two guards:
export class AuthenticationGuard implements CanActivate {
constructor(private as: AuthenticationService, private router: Router) { }
canActivate() {
if (this.as.isLoggedIn()) {
return true;
}
this.router.navigate(['/login']);
return false;
}
}
export class IsAdminGuard implements CanActivate {
constructor(private us: UserService, private router: Router) { }
canActivate() {
if (this.us.isAdmin()) {
return true;
}
this.router.navigate(['/home']);
return false;
}
}
And my route guards
const routes: Routes = [
{
path: 'home',
component: DashboardComponent,
canActivate: [AuthenticationGuard, IsAdminGuard]
}
];
@NgModule({
imports: [ RouterModule.forRoot(routes) ],
exports: [ RouterModule ]
});
What's happening is that if AuthenticationGuard
fails, it will sometimes check IsAdminGuard
and instead of routing someone to /login
when they are not authenticated, they are sent to /home
which sends them to a different error page because they are not authenticated and are not an admin and the guards should have kicked them out on the first fail.
I can reproduce the issue 100% of the time if I remove the authentication jwt that AuthenticationService
checks when it calls isLoggedIn()
, refresh the /home
route and can trace the AuthenticationGuard
returning false
and still calling IsAdminGuard
Here is the code for isLoggedIn()
isLoggedIn = () => {
const token = this.get();
const decoded = this.decode(token);
return token && this.isNotExpired(decoded);
};
decode = (token: string) => {
const validToken = () => parts.length < 3
const parts = token ? token.split('.') : '';
if (!token || validToken()) {
return '{}';
}
const payload = validToken() ? parts[1] : '{}';
return JSON.parse(atob(payload));
};
private isNotExpired = (decodedToken) => this.getExpiryFrom(decodedToken) > new Date();
private getExpiryFrom = (decodedToken) => new Date(decodedToken.exp * 1000);
thoughts?