I have routing file like this:
{
path: '',
component: LayoutComponent,
children: [
{
path: '',
component: HomeComponent,
},
{
path: 'login',
loadComponent: () =>
import('./features/login/login.component').then((m) => m.LoginComponent),
},
{
path: 'horse-catalogue',
canMatch: [isLoggedIn],
loadComponent: () =>
import('./features/horse-catalogue/horse-catalogue.component').then(
(m) => m.HorseCatalogueComponent
),
resolve: { data: horseCatalogueResolver },
},
...
}
export const isLoggedIn: CanMatchFn = () => {
const authService = inject(AuthenticationService);
return authService.isLoggedIn().pipe(map((user) => !!user));
};
authService.isLoggedIn() will make a network call to determine if the user is logged in (which I’m doing because a logged in user is issued a HttpOnly, Secure cookie; so I can’t read the cookie on the frontend. I wanted to follow a pattern where all the validation is done on the server).
I initially thought of creating another guard to attach to the HomeComponent which will do something similar (it’ll just check the inverse of isLoggedIn), but I felt that calling a verify endpoint for every user that’s not logged in seemed a bit overkill. I’ve also got an interceptor, which captures a 401 on all endpoints, and displays a notification to the user saying ‘Unauthorised’, which I wouldn’t want the user to see as soon as they navigate to the application.
Does anyone have any suggestions on how to handle this declaratively with guards?