React Router Authorization

JavascriptReactjsAuthorizationReact Router

Javascript Problem Overview


What are the best practices for authorization checking prior to a component mounting?

I use react-router 1.x

Here are my routes

React.render((
  <Router history={History.createHistory()}>
    <Route path="/" component={Dashboard}></Route>
    <Route path="/login" component={LoginForm}></Route>
  </Router>
), document.body);

Here is my Dashboard component:

var Dashboard = React.createClass({
  componentWillMount: function () {
    // I want to check authorization here
    // If the user is not authorized they should be redirected to the login page.
    // What is the right way to perform this check?
  },

  render: function () {
    return (
      <h1>Welcome</h1>
    );
  }
});

Javascript Solutions


Solution 1 - Javascript

Updated solution for React router v4

<Route 
  path="/some-path" 
  render={() => !isAuthenticated ?
    <Login/> :
    <Redirect to="/some-path" />
}/>

React router up to v3

Use 'onEnter' event and in callback check if the user is authorized:

<Route path="/" component={App} onEnter={someAuthCheck}>  

const someAuthCheck = (nextState, transition) => { ... }

Solution 2 - Javascript

With react-router 4 you have access to the Route props inside the component. To redirect a user you just have to push the new URL to the history. In your example, the code would be:

var Dashboard = React.createClass({
  componentWillMount: function () {
    const history = this.props.history; // you'll have this available
    // You have your user information, probably from the state
    // We let the user in only if the role is 'admin'
    if (user.role !== 'admin') {
      history.push('/'); // redirects the user to '/'
    }
  },

  render: function () {
    return (
      <h1>Welcome</h1>
    );
  }
});

At the docs, they show another way to do it, by using the render property, instead of component. They define a PrivateRoute, that makes the code very explicit when you define all your routes.

Solution 3 - Javascript

If you want to apply authorization on multiple components then you can do it like this.

<Route onEnter={requireAuth} component={Header}>
    <Route path='dashboard' component={Dashboard} />
    <Route path='events' component={Events} />
</Route>

For single component you can do

<Route onEnter={requireAuth} component={Header}/>

function requireAuth(nextState, replaceState) {
  if (token || or your any condition to pass login test)
  replaceState({ nextPathname: nextState.location.pathname }, 
  '/login')
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiontheoView Question on Stackoverflow
Solution 1 - JavascriptPawelView Answer on Stackoverflow
Solution 2 - JavascriptDaniel ReinaView Answer on Stackoverflow
Solution 3 - JavascriptZaman AfzalView Answer on Stackoverflow