VueJS / Vuex App - Validate JWT Token USED for Authentication

Viewed 1945

I have a VueJS App, using Vuex & Vue Router. I have 3 components (which are also pages): Home, Login and a Protected Page which requires one to be authenticated.

The login page make a POST call to the backend API which returns a token if the credentials are valid.

  methods: {
    sendCredentials: function() {
      const { email, password } = this
      this.$store.dispatch(AUTH_REQUEST, {email, password})
      .then(() => {
          this.$router.push('/')
      })
      .catch((err) => console.log(err.response));
    }
  }

Here is the related action:

actions: {
    [AUTH_REQUEST]: ({ commit, dispatch }, user) => {
        return new Promise((resolve, reject) => {
            commit(AUTH_REQUEST);
            axios.post('http://localhost:3000/api/login', user)
                .then((resp) => {
                    const token = resp.data.token;
                    localStorage.setItem('userToken', token);
                    commit(AUTH_LOGIN, token);
                    resolve(resp);
                })
                .catch(err => {
                    commit(AUTH_ERROR, err);
                    localStorage.removeItem('userToken');
                    reject(err);
                })

        });
    }

I have used navigation guard to block access to the protected page if the user is not logged in.

This is actually working: When I go the protected page, I'm asked to log in. When I use the rights credentials, I'm able to access the protected page.

I have yet a huge bug: When I put any random string on the localStorage as the userToken, I can access the protected page...

How to prevent that ?

The initial state is defined as below:

state: {
    token: localStorage.getItem('userToken') || '',
},

Is there a way to validate the userToken which I get through the localStorage when I set up the initial state of token ?

1 Answers

I have been wondering the same thing a while ago. What I ended up with is to check the token against your backend on initial loading of your page. If the token is valid you commit it to Vuex, if the token is invalid, you delete everyting from localStorage.

This leads to the outcome where someone hypothetically could replace the token after initial load with their own invalid token, but if the clientside token is already validated, what would be the point? If you want to secure against this scenario as well you could apply the same logic in your navigation guard. So not just check for a token, but validate the token against your backend on each route change and clear localStorage if invalid. I think this will come at a performance disadvantage though due to the extra API call.

Related