LookBad
LookBad

Reputation: 150

How to do JWT auth?

I create my first vue app and I have problem with authorization. I have two types of account: admin, user. My api know how-is-how from JWT.

My router:

router.beforeEach((to, _from, next) => {
  const adminLoggedIn = store.getters.getLoggedAdmin;
  const userLoggedIn = store.getters.getLoggedUser;
  const { authorize } = to.meta;

  if (authorize) {
    if (userLoggedIn) {
      if (authorize == Role.User)
        return next()
      else
        return next({ path: '/' })
    }

    if (adminLoggedIn) {
      if (authorize == Role.Admin)
        next()
      else
        return next({ path: '/' })
    }

    if (!userLoggedIn && !adminLoggedIn){
      return next({ path: '/admin/sign-in' });
    }
  }
  next();
});

My store:

export default {
  state: {
    admin: {
      name: "",
      accessLevel: -1
    }
  },
  getters: {
    getAdminJwt: () => {
      return localStorage.getItem("jwt");
    },
    getLoggedAdmin: (state) => {
      if (localStorage.getItem("jwt"))
        return state.admin;
    }
  },
  mutations: {
    setAdminJwt: (_state, payload) => {
      localStorage.setItem("jwt", payload)
    },
    setLoggedAdmin: (state, payload) => {
      state.admin.name = payload.name
      state.admin.accessLevel = payload.accessLevel
    }
  },
  actions: {
    signInAdmin: async ({ commit }, payload) => {
      axios
        .post('admin/auth/sign-in', payload)
        .then(res => {
          commit('setAdminJwt', res.data.token);
          commit('setLoggedAdmin', res.data.profile);
          router.push({ path: "/admin/add-parking-spot" })
        })
    },
}

In beforeEach method data from store aren't refreshed when I try to log user. Is this method of sign in ok? I'm new in client-apps/"front-end" and I know that this code can be so bad.

Upvotes: 0

Views: 199

Answers (1)

ellisdod
ellisdod

Reputation: 1744

The problem is that your getters are returning an attribute of localStorage which isn't reactive. So you need to set localStorage data in your store, so that your getters know when its been updated.

state: {
    user: {
      name: null,
      accessLevel: -1
    },
    jwt : null,
  },
mutations: {
    setAdminJwt: (state, payload) => {
      state.jwt = payload
    },
    setLoggedAdmin: (state, payload) => {
      state.user.name = payload.name
      state.user.accessLevel = payload.accessLevel
    }
},
getters: {
    getAdminJwt: () => {
      return state.jwt;
    },
    getLoggedAdmin: (state) => {
      return state.user
    }
  },


You don't need to use getters for the above. You can call store.state.user directly from your beforeEach function.

Upvotes: 1

Related Questions