0

I'm working on a small project using VueJS and Vue Router and Laravel in the backend.

I tried too many times to use navigation guard but didn't succeed,

I have a login component works really fine, this is my login method : (as you can see I'm using localStorage for my token and some other data)

Login.vue

login() {

      axios.post('http://proudata.test/api/login', this.user).then(response => {

        if (response.data.data.isLogged == true) {
          
          localStorage.setItem('token', JSON.stringify(response.data));

          router.push({ name: 'dashboard' });

        }

      }).catch(error => {
        this.error = true;
        this.message = error.response.data.message
      });

    }

my issue is with the navigation guard and exactly in beforeEach, I try to validate the token each time the user click on another page to check if the token is still alive or expired :

this is my routes.js file :

router.beforeEach(async (routeTo, routeFrom, next) => {
 
  const authRequired = routeTo.matched.some((route) => route.meta.authRequired)
  
  if (!authRequired) return next()

    // **THE PROBLEM IS HERE IM GETTING 401 JUST AFTER LOGIN**
    await client.get('validate-token').then(() => {
      next();
    }).catch(() => {
      next({ name: 'login' })
    });
 
});

and I have an axios client file that I use to send the header each time as you can see :

Client.js

import axios from 'axios';

let userData = localStorage.getItem('token');

let authenticated = {data:{}};

if(userData !== null){
    authenticated = JSON.parse(userData);
}

const client = axios.create({
    baseURL: ((authenticated.data.domain !== null) ? authenticated.data.domain : 'http://domain.test/api')
});

client.interceptors.request.use(config => {

    if(userData !== null){

        config.headers.Authorization = authenticated.data.token ? `Bearer ${authenticated.data.token}` : null; 
    }

    return config;

});

export default client;

the problem is : once I click on login I get my response like that : (which is correct, logged successfully )

Server Response (201), logged successfully

{
   data:{
     isLogged:true,
     token: gkljdfslkgjdfklgjfdlkgj,
     domain: http://user.multitenancy.test
   }
} 

then I get an error in validate-token I get 401, is like I'm not sending the token that I have saved in the localStorage as Bearer Authorization (check the interceptor please)

As you can see in my login method, token is saved in the localStorage, but im sending null in the Bearer Authorization, ( the problem only when I push login button to login ) and I see my localStorage data in the Devtools fine.

probably I should not verify the token in beforeEach ? What do you think the issue ?

  • The token validation endpoint seems redundant. All of your endpoints need to validate the token anyway and you can return 401 from them all the same. What purpose does this endpoint serve? – Etheryte Jun 11 '22 at 18:07
  • @Etheryte the endpoint is because Im using a multi tenancy, each subdomain = a database –  Jun 11 '22 at 18:09
  • This error occurs because laravel has a built-in CSRF protection and it expects a CSRF token in the request. Read documentation for more info. https://laravel.com/docs/9.x/csrf Also this following post might help you: https://stackoverflow.com/a/41867849/4982097 – Engin Jun 11 '22 at 18:12
  • @Engin I don't think that is the problem, because the problem is in my beforeEach, im not sending the bearer token, since i just click on login and the token just savec in the localstorage –  Jun 11 '22 at 18:14
  • what the `validation-token` end point does? – Giacomo M Jun 11 '22 at 18:18
  • @GiacomoM http://user.multitenancy.test/api/validate-token –  Jun 11 '22 at 18:24

1 Answers1

0

You need to get token from localStorage every time to get fresh data.

config.baseURL also need to set every time in your interceptor.

import axios from 'axios';

let userData = localStorage.getItem('token');

let authenticated = {data:{}};

if(userData !== null){
    authenticated = JSON.parse(userData);
}

const client = axios.create({
    baseURL: ((authenticated.data.domain !== null) ? authenticated.data.domain : 'http://domain.test/api')
});

client.interceptors.request.use(config => {
    // get token from localStorage every time to get fresh data
    let userData = localStorage.getItem('token');

    let authenticated = {data:{}};
    
    if(userData !== null){
        authenticated = JSON.parse(userData);
        config.headers.Authorization = authenticated.data.token ? `Bearer ${authenticated.data.token}` : null;
        config.baseURL = ((authenticated.data.domain !== null) ? authenticated.data.domain : 'http://domain.test/api')
    }

    return config;

});

export default client;
Paul Tsai
  • 999
  • 7
  • 13