One of the universal pains of all SPA developers is to control the access of some pages only to the authenticated users.
For example, landing pages = good. Pages inside the dashboard = no bueno.
My solution is to exploit React's special children
props and build a wrapper component around the routes I want controlled access from.
What is a children
prop?
Essentially, everything inside an opening and closing tag of a component is the children of that component. This is usually helpful in building Layout components, (if you use that design pattern, which you should).
Routes.js
In a very v3 fashion (hehe), I have a Routes
file which contains a list of all the routes available in the application.
import App from './components/App'
import Login from './components/Login'
import Messages from './components/Messages'
import Settings from './components/Settings'
import { routes } from './routes-list' // just a list of paths
export default Routes = () => {
return (
<Router>
<Switch>
<Route exact path="/" component={App}/>
<Route exact path={routes.login} component={Login}/>
// Private routes
<Route exact path={routes.messages} component={Messages}/>
<Route exact path={routes.settings} component={Settings}/>
</Switch>
</Router>
)
}
New Component: PrivateRoute
PrivateRoute
serves as a wrapper component to all of the routes that need authentication. Authentication method is highly specific to an application so you may want to use or create your own, but essentially, it should check if the user is allowed access to these private routes. Otherwise, the app redirects to /login
page.
import React, { Fragment } from 'react'
import { Redirect } from 'react-router-dom'
import { isUserAuthenticated } from './utils/auth'
export default PrivateRoute = (props) => (
<Fragment>
{ isUserAuthenticated() ? props.children : <Redirect to={routes.login} /> }
</Fragment>
)
Implementation
Inside Routes.js
, wrap the routes you need to make private.
// ...all the imports
import PrivateRoute from './components/PrivateRoute'
export default Routes = () => {
return (
<Router>
<Switch>
<Route exact path="/" component={App}/>
<Route exact path={routes.login} component={Login}/>
// Private routes
<PrivateRoute>
<Route exact path={routes.messages} component={Messages}/>
<Route exact path={routes.settings} component={Settings}/>
</PrivateRoute>
</Switch>
</Router>
)
}
That's about it!
If you are interested in knowing other implementations of authenticated routing in React (and trust me, there are lots), I have compiled here a curated list as a guide:
As always, happy coding!
Top comments (1)
Very elegant.