Adding Route Guards in MEAN Stack
In our previous section, we successfully connected the logout button and redirected the user. We still can edit or add a post if we are not authenticated by simply going to that URL directly. To prevent this, we need to guard some routes so that we cannot be able to do so. We will use the following steps to add guards:
1) We will create a guard in our auth folder, and we will name it auth.guard.ts. It is basically a typescript file.
2) This is a class that we export, and we name this class, AuthGuard. This Guard means angular add some interfaces that force the classes to add certain methods that the @angular/router can execute before it loads a route to check whether it should proceed or do something else. And one such interface which helps us with protecting routes is the CanActive interface, which we need to import from the @angular/router.
3) This CanActivate interface is implemented in the following way:
If you are not using that IDE, you have to add this method manually.
4) We will remove the throw statement, and instead of that, we will return such a Boolean. If we return true or a promise or an observable that eventually yields true and then the router will know that the route we were protecting is accessible, the user may access it. If we return false, the router will deny going there. Well before returning false, we should also navigate the user away therefore and redirect. Otherwise, we will just block the loading of the page but not provide an alternative.
5) We don't want to hardcode true or false into that file. We want to get that information from the auth service, where we store the information about whether the user is authenticated. So, we will go to that service by injecting it, and for injecting something into that auth-guard, we have to add @Injectable annotation because our auth-guard is also a service.
6) Now, we will use it in the canActivate() We will create a new constant isAuth and call the getIsAuth() method of the auth service because that holds the information whether the user is authenticated or not, and this will be updated when we will log in or logout.
7) Now, we will simply check the user is authenticated or not. If the user is authenticated, then we return true. Otherwise, we want to navigate away from the user. We will do this by injecting the router, and after injecting this, we will use the router's navigation method and pass /login in the square bracket ['/login'] to navigate to the login page.
8) Now, we need to add this Guard, and we will add it to the app routing module. Since it is a service, we need to provide it. So, we will add a provider array, and in this array, we will add our auth guard.
9) Now, we need to attach it to the routes we want to protect. We want to protect, create and edit routes. We can add another property, canActivate, which takes an array of guards we want to run on these routes whenever the router tries to load them or try to activate them.
Now, both routes are protected, and it means that if we now reload and we manually enter the create and edit page url, we will navigate to the login page.
Yeah, our auth-guard is working well. Now, we will also prevent situations where the user might do something that is doomed to fail, which would provide a bad user experience. We can now avoid this because now the user cannot get into a situation where he tries to do something he cannot do.