Building Simple CRM with Vue: Securing Routes through Effective Navigation Guards

WebCraft Notes - Mar 26 - - Dev Community

Check this post in my web notes!

As we've successfully configured the login feature in our Simple CRM, the next imperative step is to fortify our application with an added layer of protection. Today, our focus shifts to Vue Router Navigation Guards – a crucial aspect of enhancing security. In this article, we delve into the significance of guards, implementing them seamlessly into our CRM project. Additionally, we harness the power of the onAuthStateChange observer from the Firebase Auth module to elevate our security measures. We will focus today on two main parts:

1. What Role Does it Play in Vue.js Apps?

2. Mastering Navigation Guard Implementation.

Ready to implement heightened security measures? Let's integrate Navigation Guards and leverage the power of onAuthStateChange from the Firebase Auth module in our CRM project.

1. What Role Does it Play in Vue.js Apps?

Navigation Guards are protective mechanisms in Vue.js applications that regulate and control the navigation process. Think of them as gatekeepers ensuring secure and seamless transitions between different routes in your app. These guards intercept navigation requests, allowing you to impose conditions or perform actions before permitting or denying access to specific routes. They play a crucial role in enhancing user experience and application security by enabling you to manage authentication, authorization, and other custom checks. In essence, Navigation Guards act as vigilant custodians, safeguarding the flow of your Vue.js app and ensuring that users traverse the digital landscape safely and securely.

Vue.js provides three types of navigation guards: global guards, per-route guards, and in-component guards.

Global Guards:

  • beforeEach: Executed before each navigation. Useful for global checks or actions.

  • beforeResolve: Similar to beforeEach but is called after the navigation is confirmed, and components matched.

  • afterEach: Called after each navigation. Useful for tasks like logging or analytics.

Per-Route Guards:

  • beforeEnter: Applied at the route level and executed before the component is instantiated.

  • beforeRouteUpdate: Called when the route is reused (e.g., when navigating to the same component with different parameters).

  • beforeRouteLeave: Invoked when navigating away from the current route.

In-Component Guards:

  • beforeRouteEnter: Called before the component is even created, making it challenging to access the component instance.

  • beforeRouteUpdate: Similar to the global beforeRouteUpdate but specific to the component.

  • beforeRouteLeave: Specific to the component, executed when leaving the route.

These guards offer flexibility and control at various stages of the navigation process, allowing developers to implement custom logic or checks as needed for a Vue.js application.

2. Mastering Navigation Guard Implementation.

We will implement global Navigation Guards to check if the user logged in and if the user has permission to visit the route. For that purpose, we will use an onAuthStateChange observer from the Firebase Authentication module. Let's start.

Open our router file and after all routes add router.beforeEach the navigation Guard. This Navigation Guard accepts 3 params to, from, and next, and also imports our auth module from Firebase.

Okay, the auth module stores our currentUser state from Firebase, and if it exists then our user is logged in, else he needs to log in. Yes, so simple... Also, do not forget to prevent possible redirection repeat!!

router.beforeEach(async (to, from, next) => {
  const user = auth.currentUser;
    if (!user && to.name !== 'Login' && to.name !== 'SignUp') {
      next({ name: 'Login' });
    } else {
      next();
    }
});
Enter fullscreen mode Exit fullscreen mode

Great, now every time the user moves between routes our navigation guard will check if the user is still logged in, and if not user will be redirected to the Login page.

Next, open our Main Layout component. Import the onAuthStateChange method from the Firebase auth module and our auth pinia store.

import { auth } from '@/firebase/firebase';
import { onAuthStateChanged } from 'firebase/auth';
import { useAuthStore } from '@/stores/auth';
Enter fullscreen mode Exit fullscreen mode

Now, inside the created lifecycle hook we will check if the state did not change and if the user logged in then we will get user data, and if not send the user to the Login page.

created() {
    onAuthStateChanged(auth, async (user) => {
        if (!user && !this.authStore.gUser) {
            this.$router.push('/auth/login');
        } else if (user && !this.authStore.gUser) {
            await this.authStore.aGetUser(user.uid);
        }
    })
}
Enter fullscreen mode Exit fullscreen mode

I think it will even double-protect our routes.

In conclusion, fortifying your Vue.js applications with Navigation Guards is a pivotal step in ensuring both security and a seamless user experience. By regulating navigation processes, these guards act as vigilant custodians, safeguarding the flow of your Vue CRM app. The flexibility offered by global, per-route, and in-component guards empowers developers to implement custom logic and checks tailored to their application's needs. Mastering the implementation of Navigation Guards, particularly through the onAuthStateChange observer from Firebase Auth, adds an extra layer of protection by checking user authentication status at various stages.

Stay tuned for more insightful Vue.js development tips and tricks!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .