How to implement authenticated routes in React Router 4?

Tags: , , ,

I was trying to implement authenticated routes but found that React Router 4 now prevents this from working:

<Route exact path="/" component={Index} />
<Route path="/auth" component={UnauthenticatedWrapper}>
    <Route path="/auth/login" component={LoginBotBot} />
<Route path="/domains" component={AuthenticatedWrapper}>
    <Route exact path="/domains" component={DomainsIndex} />

The error is:

Warning: You should not use <Route component> and <Route children> in the same route; <Route children> will be ignored

In that case, whats the correct way to implement this?

It appears in react-router (v4) docs, it suggests something like

        <li><Link to="/public">Public Page</Link></li>
        <li><Link to="/protected">Protected Page</Link></li>
    <Route path="/public" component={Public}/>
    <Route path="/login" component={Login}/>
    <PrivateRoute path="/protected" component={Protected}/>

But isit possible to achieve this while grouping a bunch of routes together?


Ok, after some research, I came up with this:

import React, {PropTypes} from "react"
import {Route} from "react-router-dom"

export default class AuthenticatedRoute extends React.Component {
  render() {
    if (!this.props.isLoggedIn) {
      return null
    return <Route {...this.props} />

AuthenticatedRoute.propTypes = {
  isLoggedIn: PropTypes.bool.isRequired,
  component: PropTypes.element,
  redirectToLogin: PropTypes.func.isRequired

Isit correct to dispatch an action in render() it feels wrong. It doesnt really seem correct with componentDidMount or some other hook either?


You’re going to want to use the Redirect component. There’s a few different approaches to this problem. Here’s one I like, have a PrivateRoute component that takes in an authed prop and then renders based on that props.

function PrivateRoute ({component: Component, authed,}) {
  return (
      render={(props) => authed === true
        ? <Component {...props} />
        : <Redirect to={{pathname: '/login', state: {from: props.location}}} />}

Now your Routes can look something like this

<Route path='/' exact component={Home} />
<Route path='/login' component={Login} />
<Route path='/register' component={Register} />
<PrivateRoute authed={this.state.authed} path='/dashboard' component={Dashboard} />

If you’re still confused, I wrote this post that may help – Protected routes and authentication with React Router v4

Source: stackoverflow