Authenticated routes using react-router
source link: https://willschenk.com/articles/2017/authenticated_routes_using_react_router/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Authenticated routes using react-router
Published December 5, 2017 #react #howto
Here’s a simple walk through on how to use authenticated routes with react-router.
create-react-app route-test
cd route-test
yarn add react-router-dom
And for src/App.js
:
import React, { Component } from 'react';
import {
BrowserRouter as Router,
Route,
Link,
Switch
} from 'react-router-dom';
const Nav = () => (
<ul>
<li><Link to='/'>Home</Link></li>
<li><Link to='/about'>About</Link></li>
<li><Link to='/session'>Session</Link></li>
<li><Link to='/secret'>Secret</Link></li>
</ul>
)
const Welcome = () => (
<div>
<h1>Welcome</h1>
<p>This is some text</p>
</div>
)
const About = () => (
<div>
<h1>About</h1>
<p>Sure, stuff</p>
</div>
)
const Secret = () => (
<div>
<h1>This is a secret</h1>
<p>Sorry, not everyone can see this</p>
</div>
)
const Session = ({login}) => (
<div>
<button onClick={login}>Click me</button>
</div>
)
class App extends Component {
state = {login: false}
login = () => {this.setState( {login: true} ) }
render() {
return (
<Router>
<div>
<Nav/>
{ this.state.login && <p>Logged in</p>}
<Switch>
<Route path="/secret" component={Secret}/>
<Route path="/about" component={About}/>
<Route path="/session" component={() => <Session login={this.login}/> } />
<Route component={Welcome}/>
</Switch>
</div>
</Router>
);
}
}
export default App;
- We are using Stateless Functional Components to model out our nav bar, and a few pages.
Link
is what we use to create a link to something that we define in our router. This needs to be a child of aRouter
, so ourNav
component must be a child of that.Switch
is where we are putting out routes to keep everything nice and tidy.- We have a very simple login system here, where if you go to
/session
and push a button, you are considered logged in.
Secret isn’t so secret
Lets create an authenticated component. The idea is that if the user is not authenticated, we will redirect to /session
which will show whatever login form we have.
import React, { Component } from 'react';
import { Route, Redirect } from 'react-router-dom'
class AuthenticatedRoute extends Component {
render() {
const {authed, component: Component, ...rest} = this.props;
if( authed ) {
return <Route {...rest} render={(props) => <Component {...props }/>}/>
} else {
return <Route {...rest} render={(props) => <Redirect to={{pathname: '/session', state: {from: props.location}}} />}/>
}
}
}
export default AuthenticatedRoute;
Now we just need to update the switch to use the new AuthenticatedRoute
. We are passing in an authed
property that the main App
component is maintaining.
<AuthenticatedRoute authed={this.state.login} path=”/secret” component={Secret}/>
Now we need to update the Session
component to handle the login. In the case that we aren’t logged in, we show a button that calls the login
method on the container component. This will change the login state and trigger a rerender of the components. Once that happens, authed
will be true so we look inside of the location
property to see if there was a protected route stored in the router history state. If so, we redirect back to that. Otherwise, we redirect back to home.
const Session = ({authed,location,login}) => {
if( authed ) {
let l = location.location;
let pathname = "/";
if( l && l.state && l.state.from ) {
pathname = l.state.from.pathname;
}
return <Redirect to={pathname}/>
} else {
return (
<div>
<button onClick={() => {login()}}>Click me</button>
</div>
)
}
}
And finally, we need to wire all this up in the main routes.
<Route path="/session" render={(location) => <Session location={location} login={this.login} authed={this.state.authed}/> }/> } />
Here we aren’t just passing in component={Session}
but rather a function that gets wired up to a number of local callbacks. This is mainly so that the login
function can call setState
and then trigger the render. In a case where this would be something that came from a server, you could use the normal asynchronous methods and not need to force this directly.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK