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.
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.
Two ways to handle redirecting on a user event such as create, update and delete with React Router.
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.
I would try something like this:
this.context.router.transitionTo()
).// 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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With