We recently switched over from Iron-Router to React-Router, and there are two patterns you may want to consider.
The first, which our company decided to go with, is to handle any authentication logic in your route component’s componentWillMount lifecycle method. In here, you can do as LawJolla suggests and import browserHistory to do something like:
import React, { Component } from 'react';
import { browserHistory } from 'react-router';
import { isLoggedIn } from './route-authentication.js';
class HomePage extends Component {
componentWillMount() {
/**
* Here the user will be redirected to the '/auth' route,
* if they do not meet the isLoggedIn requirements.
*/
if (!isLoggedIn()) {
browserHistory.push('/auth');
}
}
render() {
return (
<div>
Hello, World!
</div>
);
}
}
To use the above method however, you have to have browserHistory enabled on react-router, as the default is hashHistory.
Alternatively, Route Components from react-router have an API for a onEnter method. Where you could do something like:
/**
* In authentication file...
*/
import Meteor from 'meteor/meteor';
export const isLoggedIn = (nextState, replace) => {
/**
* If there is no User currently logged in, redirect them
* to the '/auth' route.
*/
if (Meteor.user === null) {
replace({
pathname: '/auth'
});
}
}
/**
* In Router file...
*/
import { isLoggedIn, otherEnterHookHere } from './authentication.js';
<Router>
<Route path="/app" onEnter={isLoggedIn} />
<Route path="/auth" onEnter={otherEnterHookHere} />
</Router>
These are very basic examples and you should definitely take a look at the API for react-router a bit more in-depth on their Github page. We went with the first pattern, simply because we were handling our data-loading through createContainer on the same component, and wanted to keep the Router logic clean. Let me know if this helps at all.
You should do authentification on the component level. You can do this in a “AppLayoutComponent” that is shared between different routes, no duplicated code.
By the way, I want to raise the question if it is a good practice to redirect not logged in users to a different route. If you do so, you’ll need to redirect the user back where he came from.
My usual approach is to just show the login form on any route that needs authentication, if the user is not logged in.
E.g. if he or she’s on /Auth and not logged in, simply show him a login form:
{ user ? <ComponentThatNeedsAuth /> : <LoginForm /> }
If user logs in, he or she will stay on /Auth, but will see