Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How redirect to login page when got 401 error from ajax call in React-Router?

I am using React, React-Router and Superagent. I need authorization feature in my web application. Now, if the token is expired, I need the page redirect to login page.

I have put the ajax call functionality in a separated module and the token will be send on each request's header. In one of my component, I need fetch some data via ajax call, like below.

 componentDidMount: function() {

    api.getOne(this.props.params.id, function(err, data) {
      if (err) {
        this.setErrorMessage('System Error!');
      } else if (this.isMounted()) {
        this.setState({
          user: data
        });
      }
    }.bind(this));

  },

If I got 401 (Unauthorized) error, maybe caused by token expired or no enough privilege, the page should be redirected to login page. Right now, in my api module, I have to use window.loication="#/login" I don't think this is a good idea.

var endCallback = function(cb, err, res) {

  if (err && err.status == 401) {
    return window.location('#/login');
  }

  if (res) {
    cb(err, res.body);
  } else {
    cb(err);
  }
};

get: function(cb) {
  request
    .get(BASE_URL + resources)        
    .end(endCallback.bind(null, cb));
},

But, I can't easily, call the react-router method in my api module. Is there an elegant way to implemented this easy feature? I don't want to add an error callback in every react components which need authorized.

like image 350
Chris Avatar asked Aug 31 '15 06:08

Chris


People also ask

How do I redirect a login page in react JS?

Redirect User to Login Page Using Navigateimport { Navigate } from "react-router-dom"; To redirect unauthenticated users, use it as follows. The Navigate component is a declarative API. It relies on a user event, which in this case is authentication to cause a state change and consequently cause a component re-render.

What are two ways of handling redirect with React Router?

Two ways to handle redirecting on a user event such as create, update and delete with React Router.

How do I fix attempted import error redirect is not exported from React-Router-Dom?

To Solve Attempted import error: 'Redirect' is not exported from 'react-router-dom' Error If You are using react-router-dom v6 Redirect component has been removed from the react-router version 6 and Redirect is Replaced Navigate so Just Use Navigate instead of Redirect.


1 Answers

I would try something like this:

  1. Use the component's context to manipulate the router (this.context.router.transitionTo()).
  2. Pass this method to the API callout as a param.

// component.js
,contextTypes: {
  router: React.PropTypes.func
},
componentDidMount: function() {
    api.getOne(this.props.params.id, this.context.router, function(err, data) {
      if (err) {
        this.setErrorMessage('System Error!');
      } else if (this.isMounted()) {
        this.setState({
          user: data
        });
      }
    }.bind(this));
},


// api.js
var endCallback = function(cb, router, err, res) {

  if (err && err.status == 401) {
    return router.transitionTo('login');
  }

  if (res) {
    cb(err, res.body);
  } else {
    cb(err);
  }
};

get: function(cb, router) {
  request
    .get(BASE_URL + resources)        
    .end(endCallback.bind(null, cb, router));
},

I know you didn't want a callback on each authenticated component, but I don't think there's any special react-router shortcuts to transition outside of the router.

The only other thing I could think of would be to spin up a brand new router on the error and manually send it to the login route. But I don't think that would necessarily work since it's outside of the initial render method.

like image 75
BradByte Avatar answered Oct 17 '22 07:10

BradByte