0
votes

My project is using vuex, axios, vue-cookies and JWTs. I have a file called api.js which is imported into my main vue js, api.js code below;

import axios from 'axios'
import Vue from 'vue'
import { store } from "@/store";

export default axios.create({
    baseURL: store.state.endpoints.baseUrl,
    headers: {
        Authorization: `JWT ${Vue.$cookies.get('token')}`,
        'Accept': 'application/json',
        'Content-Type': 'application/json'
    }
})

When I login via my login page everything appears successful. In the inspector the cookie 'token' value updates correctly with the new token, Vuex updates to show that the user isAuthenticated and the router redirects me to the homepage. Once on the homepage, if I try to navigate to a page that makes any call which requires authentication, in the header it passes 'JWT null' instead of the token in the cookie and fails and I end up in a perpetual cycle of successfully logging in but not able to go anywhere.

If I login and then refresh the page before doing anything else, everything works as expected and the JWT is no longer null. It appears that the api.js code at the top of this question is not correctly pulling the token from the cookie each time it's called but only on page refresh, is this being cached or do I need to somehow reload this import after login?

For reference, a snippet of code from my login page to show how the data is being updated after login;

  api.post(this.$store.state.endpoints.obtainJWT, payload)
      .then((response) => {
        console.log("Token - "+response.data.token);
        console.log("Profile - "+response.data.user);
        this.$cookies.set('token', response.data.token);
        this.$store.commit("setAuthUser",
            {authUser: response.data, isAuthenticated: true})
      })
      .then(() => this.$router.push({path: '/'}))
      .catch((error) => {
        console.log("Error!");
        console.log(error);
        console.debug(error);
        console.dir(error);
      })

and an example of an api call which contains 'JWT null' if accessed before refreshing the page;

import api from "../api.js";
...
api.get("/data_full/" + id)
  .then((response) => {
    this.title = response.data.title;
  })

and in my projects main.js, the api.js import;

...
import api from './api.js'
...
Vue.$http = api;
1

1 Answers

0
votes

Reading my question after posting I had a realisation that the issue isn't the get('token') call, its that I'm creating an Axios instance which is clearly not being recreated after a token is being saved to a cookie.

I've now moved code relating to the authorization header out of api.js and into the main.js as an interceptor. This way, the token value in the cookie is pulled each time an Axios call is made. This has resolved my issues. Updated code in main.js below;

    ...
    api.interceptors.response.use(
        config => {
            const token = Vue.$cookies.get('token');
            if ( token != null ) {
                config.headers.Authorization = `JWT ${token}`;
            }
            return config
        },
    ...