How to redirect from axios interceptor with react Router V4?

后端 未结 8 2102
忘了有多久
忘了有多久 2021-01-30 17:36

I want to make a redirection in axios interceptors when receiving a 403 error. But how can I access the history outside React components ?

In Navigating Programatically

8条回答
  •  北海茫月
    2021-01-30 18:21

    I solved that by accessing my Redux Store from outside the Component tree and sending it my same action from the logout button, since my interceptors are created in a separated file and loaded before any Component is loaded.

    So, basically, I did the following:

    At index.js file:

    //....lots of imports ommited for brevity
    import { createStore, applyMiddleware } from 'redux';
    import reduxThunk from 'redux-thunk';
    import reducers from './reducers';
    import { UNAUTH_USER } from './actions/types'; //this is just a constants file for action types.
    
    const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
    const store = createStoreWithMiddleware(reducers);
    
    //Here is the guy where I set up the interceptors!
    NetworkService.setupInterceptors(store);
    
    //lots of code ommited again...
    //Please pay attention to the "RequireAuth" below, we'll talk about it later
    
    ReactDOM.render(
      
          
              
    , document.querySelector('.main-container'));

    And at the network-service.js file:

    import axios        from 'axios';
    import { UNAUTH_USER } from '../actions/types';
    
    export default {
      setupInterceptors: (store) => {
    
        // Add a response interceptor
        axios.interceptors.response.use(function (response) {
            return response;
        }, function (error) {
            //catches if the session ended!
            if ( error.response.data.token.KEY == 'ERR_EXPIRED_TOKEN') {
                console.log("EXPIRED TOKEN!");
                localStorage.clear();
                store.dispatch({ type: UNAUTH_USER });
            }
            return Promise.reject(error);
        });
    
      }
    };
    

    Last, but not least, I have a HOC (Higher Order Component) that I wrap my protected components where I do the actual redirect when the session is out. That way, when I trigger the action type UNAUTH_USER, it sets my isLogged property at my session reducer to false and therefore this component gets notified and does the redirect for me, at any time.

    The file for require-auth.js component:

    import React, { Component } from 'react';
    import { connect } from 'react-redux';
    
    export default function(ComposedComponent) {
    
        class RequireAuth extends Component {
    
            componentWillMount() {
                if(!this.props.session.isLogged) {
                    this.props.history.push('/login');
                }
            };
    
            componentWillUpdate(nextProps) {
                if(!nextProps.session.isLogged) {
                    this.props.history.push('/login');
                }
            };
    
            render() {
                return 
            }
        }
    
        function mapStateToProps(state) {
            return { session: state.session };
        }
    
        return connect(mapStateToProps)(RequireAuth);
    }
    

    Hope that helps!

提交回复
热议问题