Home > OS >  Vue Javascript save jwt as cookie and wait till it is saved
Vue Javascript save jwt as cookie and wait till it is saved

Time:03-14

My login page sends login/password to the backend, receives jwt token, saves it to the cookies and redirects to /home.

The /home route has Authentication check by getting cookie by name. The problem is that at the moment, when authentication is checked immediately after login, token is undefined and no redirect takes place

router

const routes = [
  {
    path: '/login',
    component: Login,
    beforeEnter: (to, from, next ) => {
      if(isAuthenticated()) next("/home");
      else next()
    }
  },
  {
    path: '/',
    redirect: '/login'
  },
  {
    path: '/home',
    component: Menu
  }

];
router.beforeEach((to, from, next) => {
  if(!isAuthenticated() && to.path !== '/login') next('/login');
  else next();
});

authentication check middleware

export const isAuthenticated = () => {
    const token = getCookie("token");
    console.log(token)
    if (token) {
        const jwt = parseJwt(token)
        if (Date.now() >= jwt.exp * 1000) {
            console.log('unauthenticated - expired token')
            return false
        } else {
            console.log('authenticated - valid token')
            return true
        }
    } else {
        console.log('unauthenticated - no token in cookie')
        return false
    }
}

const getCookie = (name) => {
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) return parts.pop().split(';').shift();
}


const parseJwt = (token) => {
    var base64Url = token.split('.')[1];
    var base64 = base64Url.replace(/-/g, ' ').replace(/_/g, '/');
    var jsonPayload = decodeURIComponent(atob(base64).split('').map(function(c) {
        return '%'   ('00'   c.charCodeAt(0).toString(16)).slice(-2);
    }).join(''));

    return JSON.parse(jsonPayload);
}

Store action

login({ commit }, loginRequest) {
    commit("LOGIN_PENDING")

    axios.post("/api/login", loginRequest)
    .then(
      (response) => {
        document.cookie =`token=${response.data.token}`;
        commit("SET_TOKEN", response.data.token);
        commit("LOGIN_COMPLETE");
      },
      (error) => {
        if(error.response.status==401) {
          commit("SET_INVALID_LOGIN_CREDENTIALS", true);
          commit("LOGIN_COMPLETE");
        }   
      }
    )
  }

How to save the token to the cookie (document.cookie =token=${response.data.token}; ) and wait till it is saved before proceeding to the next steps?

Any help is appreciated!

CodePudding user response:

if all you wish is to store the authentication state, I would suggest you to use cookie-session on backend... it would automatically handles all this for you - https://www.npmjs.com/package/cookie-session

CodePudding user response:

I have figured out the reason of the problem - the login acction in the vuex was not desclared as asynchronous, so I made added async to the login, await to the axios post and the problem was solved

async login({ commit }, loginRequest) {
    commit("LOGIN_PENDING")

    await axios.post("/api/login", loginRequest)
    .then(
      (response) => {
        document.cookie =`token=${response.data.token}`;
        commit("SET_TOKEN", response.data.token);
        commit("LOGIN_COMPLETE");
      },
      (error) => {
        if(error.response.status==401) {
          commit("SET_INVALID_LOGIN_CREDENTIALS", true);
          commit("LOGIN_COMPLETE");
        }   
      }
    )
  }
  • Related