Authentication in Vue Router

Vue router has a simple job - receive client-side requests and invoke the view that needs to be rendered in the browser. That is also a powerful job.

Typically, this is what you see in a Vue router -

// client/router.js

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue"; // views!
import store from "./store/index"; // store (will be used subsequently)

Vue.use(Router);
export default new Router({
  mode: "history", // include URL in browser history
  base: "/", // base URL. if your app is at "/app", specify here
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/todo",
      name: "todo",
      component: () => import("./views/Todo.vue") // lazy render
    }
  ]
});

Router is simple and self-explanatory. User clicks on a link on the UI that says “/”, she is taken to Home component. She clicks on “/todo” on UI, browser navigates to Todo.

The link itself will be defined on the UI using -

<router-link to="/">Home</router-link>
<router-link to="/todo">My Todo</router-link>

Now, let’s say we want to prevent user from navigating to Todo if she is not authenticated yet. We can accomplish that in the vue router in a couple of lines of code.

First define the function that is responsible to check whether user has logged in (place it before the export default statement).

function checkAuth(to, from, next) {
  if (store.state.isLoggedIn) next();
  else "/login";
}

The function gets default parameters that is available to a route. It finds out whether user is logged in - we are using an isLoggedIn state variable from store. This value has been assumed to be set by you at the time of login.

Then, navigate to /todo if user has been authenticated, otherwise go to /login.

Next, call this function when route is invoked.

// .. code
  {
      path: "/todo",
      name: "todo",
      component: () => import("./views/Todo.vue"), // lazy render
      beforeEnter: checkAuth,
    },
// .. code

Vue invokes the function when the My Todo link is clicked and navigates to defined views depending on the authentication.

Below is the entire code ..

// client/router.js

import Vue from "vue";
import Router from "vue-router";
import Home from "./views/Home.vue"; // views!
import store from "./store/index";

Vue.use(Router);

function checkAuth(to, from, next) {
  if (store.state.isLoggedIn) next();
  else "/login";
}

export default new Router({
  mode: "history", // include URL in browser history
  base: "/", // base URL. if your app is at "/app", specify here
  routes: [
    {
      path: "/",
      name: "home",
      component: Home
    },
    {
      path: "/todo",
      name: "todo",
      component: () => import("./views/Todo.vue") // lazy render
      beforeEnter: checkAuth,
    }
  ]
});

You can use the same logic to enforce dynamic routing. For e.g. consider the below code that navigates user to two different views based on role.

function adminHome(to, from, next) {
  if (store.state.index.role == "admin") next("/admin-dashboard);
  else "/dashboard";
}
comments powered by Disqus