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);
    

Log in to reply