Axios interceptor and router push not working



  • I am trying to push users back to the login page if authentication fails. However in a Axios interceptor the router push doesn’t seem to work. Are there good any other ways that i can deal with a authentication fail?

    import Vue from 'vue'
    import axios from 'axios'
    import store from '../store';
    
    // request interceptor
    axios.interceptors.request.use(
        config => {
            const token = store().getters['auth/accessToken'];
            if (token) {
                config.headers['Authorization'] = 'Bearer ' + token;
            }
            return config;
        },
        error => {
            Promise.reject(error)
        });
    
    // response interceptor
    axios.interceptors.response.use((response) => {
            return response
        },
        function (error) {
    
            if (error.response.status === 401 && !window.refreshing) {
                window.refreshing = true;
                return axios.post('http://posadmin/api/auth/refresh',
                    {
                        "refresh_token": store().getters['auth/refreshToken']
                    })
                    .then(res => {
                        console.log(res.status);
                        console.log(res.data);
                        if (res.status === 200) {
                            store().commit("auth/refreshToken", res.data);
                            axios.defaults.headers.common['Authorization'] = 'Bearer ' + store().getters['auth/accessToken'];
    
                            return axios(error.config);
                        } else {
                            console.log('200 else');
                            store().dispatch("auth/setLogout");
                            this.$router.push('/login');
                        }
                    })
                    .catch((error) => {
                        console.log(window.refreshing);
                        console.log('catch '+error);
                        store().dispatch("auth/setLogout");
                        this.$router.push('/login');
                    });
            }
    
            // return Error object with Promise
            return Promise.reject(error);
        });
    
    Vue.prototype.$axios = axios;
    
    
    


  • You can simply use window.location = '/#/login'



  • Does it work? What @jraez said should help.

    If you really want to use the router, you can do that, too.
    The code you showed is in a boot file, right? So I think your this.$router.push('/login') call doesn’t work because this.$router is not defined. Normally, you write that in a Vue component, where this refers to the component - but you are in a boot file.

    This is how you can do it:

    import axios from "axios"
    
    export default ({ Vue, router }) => { // <-------- This is where the `router` comes from
      Vue.prototype.$axios = axios;
    
      // ... (your request interceptor here)
    
      axios.interceptors.response.use(response => {
        return response;
      }, error => {
        if (error.response.status === 401) {
          // ...
          router.push("/login"); // <----  note there is no `this`
        }
        // ...
      });
    }
    


  • Quick note: Vue warn again calling VueX methods such as dispatch or commit outside of a Vue component. Example:

     store().commit("auth/refreshToken", res.data);
    


  • Hello!
    Were you able to make router.push work?
    I can’t seem to get it to work. 😞

    ‘’’
    import Vue from ‘vue’
    import axios from ‘axios’
    import { Notify } from ‘quasar’
    import router from ‘…/router’

    const axiosInstance = axios.create({
    baseURL: process.env.API
    })

    axiosInstance.interceptors.response.use(response => {
    return response
    }, error => {
    if (error.response.status === 401) {
    Notify.create({
    type: ‘negative’,
    timeout: 1000,
    position: ‘top’,
    message: error.response.data.message
    })
    router.push(’/login’)
    return Promise.reject(error)
    }
    })

    Vue.prototype.$axios = axiosInstance
    export { axiosInstance }

    ‘’’



  • @mflorindo router is passed as an argument inside your bootfile https://quasar.dev/quasar-cli/boot-files#Anatomy-of-a-boot-file. or you can expose it from your src/router/index.js file. like this

    let router = null
    export default function ({ store }) {
      router = new VueRouter({ ... })
      ...
      return router
    }
    
    export { router }
    
    //somefile.js then you can import it
    import { router } from '…/router’
    

Log in to reply