My vuejs navigation guard not working as expected

1.7k Views Asked by At

i am using vuex for statemanagement this is my vuex code ,

here my logic is if token is exist in local storage then it will set isAuthenticated to true so it will be easy to check against routes.but some how its not working.

import axios from "axios";
import router from "../../router";

const state = {
  token: localStorage.getItem("tkn") || "",
  isAuth: false,
};

const getters = {
  isAuthenticated: (state) => !!state.token,
  authStatus: (state) => state.isAuth,
};

const actions = {
  login({ commit }, loginData) {
    // commit('auth_request')
    axios
      .post("/api/adminuser/auth/login", loginData)
      .then((resp) => {
        console.log(resp);
        localStorage.setItem("tkn", resp.data.token);

        axios.defaults.headers.common["Authorization"] = resp.data.token;

        commit("setToken", resp.data.token);

        router.push("/");
      })
      .catch((err) => {
        console.log(err);

        commit("authError", err);
        localStorage.removeItem("token");
      });
  },
};

const mutations = {
  setToken: (state, token) => ((state.token = token), (state.isAuth = true)),
  authError: (state) => (state.isAuth = false),
};

export default {
  state,
  getters,
  actions,
  mutations,
};

and this is my router code

import Vue from "vue";
import VueRouter from "vue-router";
import auth from "../store/modules/auth.js";

Vue.use(VueRouter);

const routes = [
  {
    path: "/signin",
    name: "signin",
    component: () => import("../components/Authentication/Signin.vue"),
  },

  {
    path: "/",
    name: "dashboard",
    component: () => import("../components/Dashboard/Dashboard.vue"),
    meta: {
      requiresAuth: true,
    },
  },
];

const router = new VueRouter({
  mode: "history",
  routes,
});

router.beforeEach((to, from, next) => {
  if (to.name !== "signin" && auth.getters.isAuthenticated == false)
    next({ name: "signin" });
  else next();
});


export default router;

currently if i do login still i can go to signin page and even i can goto dashboard without authentication.

2

There are 2 best solutions below

3
On

You should create store before you use

// auth.js
import Vue from 'vue'
import Vuex from 'vuex'
import router from "../../router";

Vue.use(Vuex)
// ....
export default new Vuex.Store({
 state,
 getters,
 actions,
 mutations,
});

Otherwise the auth.getters.isAuthenticated will be the function, not the vuex getters.

The vuex guide is here https://vuex.vuejs.org/guide/

1
On

Please make a functions like below, in some file say helper.js and initialize it in main.js

helper.js

import axios from 'axios';
export function initialize(store, router) 
{  router.beforeEach((to,from,next)=>{ 
   const requiresAuth= to.matched.some(record=>record.meta.requiresAuth)
   const currentUser = store.state.isAuthenticated;
   if(requiresAuth && !currentUser){ next('/signin');} 
   else if(to.path=='/signin' && currentUser){ next('/')}
   else { next()}
  })
}

in your main.js

import {initialize} from './helper';
import router from './router'
import store from './store'
initialize(store, router);

Login page

methods: {
...mapActions(["login"]),
loginUser: function(event) {
       event.preventDefault();
       this.login({ email: this.email, password: this.password })
           .then(()=>{ this.$router.replace({name:'dashboard'})
                        //forward to this path after login
                     }).catch(()=>{console.log('login fail')   });
      }
},