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.
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.