react-router
I'm a full-stack product engineer.
I build dumb fun web stuff and work on rusty old cars.
Stream lets you build scalable and personalized activity feeds.
If you'd like to revisit this talk later:
Slides: | ken.hoff.tech/slides/frontend-authed-routes |
Source code: | github.com/kenhoff/frontend-authed-routes |
Live demo: | kenhoff.github.io/frontend-authed-routes |
Winds is an RSS reader and podcast player that will showcase activity feeds from Stream.
react-router
and how to build "frontend authenticated routes" with it
Authentication vs Authorization
react-router
react-router
theory, example, and practiceRoute
component - path
, component
, and render
propsAuthedRoute
and UnauthedRoute
componentsreact-router
doesRenders different React components based on window location
Change page content with no refreshes
Quick demo: kenhoff.github.io/frontend-authed-routes/
react-router
<Router history={createBrowserHistory()}>
<div>
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/pricing">Pricing</Link></li>
<li><Link to="/about">About</Link></li>
</ul>
<Route path="/home" component={Home}></Route>
<Route path="/pricing" component={Pricing}></Route>
<Route path="/about" component={About}></Route>
</div>
</Router>
Need to bench test? create-react-app
is probably the easiest
react-router
componentsRouter
Route
Link
Redirect
Just reload the page!
unauthed user → /my-account
→ hard redirect to /sign-in
unauthed user → /sign-in
→ authenticates → hard redirect to /my-account
Frontend authed routes == No hard redirects when authenticating
nice to have in web apps, but really important with desktop/native/progressive/electron apps
Users | Source | Destination |
---|---|---|
All users | /home | stay put :) |
All users | /pricing | stay put :) |
All users | /about | stay put :) |
Unauthed users | /my-settings | /sign-in |
Authed users | /sign-in | /my-settings |
"Authed Route" - only render the component if the user is authenticated (otherwise, redirect)
"Unauthed Route" - only render the component if the user is not authenticated (otherwise, redirect)
If we don't care if the user is authed or not, just use plain Route
Route
has something built in for this?Route
componentpath | the URL to match (can include route params, like with express ) |
component | the component to render if the path matches (can include nested routes!) |
render (function) | called if the path matches (return a React component or element) |
<Route path="/pricing" component={Pricing} />
<Route path="/about" render={() => {
return (<About />);
}} />
render
prop (only called when path matches)render
, check to see if the user is authenticated or notRedirect
to /sign-in
<Route path="/my-settings" render={(props) => {
if (userIsAuthenticated()) {
return (<Settings {...props}></Settings>);
} else {
return (<Redirect to="/sign-in"></Redirect>)
}
}}></Route>
(why do we have to include ...props
?)
(basically the opposite of our "Authed Route")
<Route path="/sign-in" render={(props) => {
if (userIsAuthenticated()) {
return (<Redirect to="/my-settings"></Redirect>)
} else {
return (<SignIn {...props}></SignIn>);
}
}}></Route>
I want a bunch of authed and unauthed routes -
/my-settings
, /my-profile
, /billing
/create-account
, /sign-in
, /forgot-password
, /reset-password
/home
, /pricing
, /about
Want something reusable and easy-to-read
Something like "AuthedRoute
" and "UnauthedRoute
"
Still want to use Route
for routes that we don't care about auth on
AuthedRoute
componentputting it all together....
AuthedRoute
componentAuthedRoute
renders a Route
render
prop (only called when path matches)component
(passed in as props)Redirect
to /sign-in
composition yay!
AuthedRoute
component let AuthedRoute = ({
component: Component,
...rest
}) => {
return <Route {...rest} render={(props) => {
if (userIsAuthenticated()) {
return (<Component {...props}></Component>);
} else {
return (<Redirect to="/sign-in"></Redirect>)
}
}}></Route>
}
<AuthedRoute path="/my-settings" component={Settings}></AuthedRoute>
UnauthedRoute
component....is basically the opposite of the AuthedRoute
component
let UnauthedRoute = ({
component: Component,
...rest
}) => {
return <Route {...rest} render={(props) => {
if (userIsAuthenticated()) {
return (<Redirect to="/my-settings"></Redirect>)
} else {
return (<Component {...props}></Component>);
}
}}></Route>
}
<UnauthedRoute path="/sign-in" component={SignIn}></UnauthedRoute>
Router
<Router history={createBrowserHistory()}>
<div>
<ul>
<li><Link to="/home">Home</Link></li>
<li><Link to="/pricing">Pricing</Link></li>
<li><Link to="/about">About</Link></li>
<li><Link to="/my-settings">My settings (authed)</Link></li>
<li><Link to="/sign-in">Sign in (unauthed)</Link></li>
</ul>
<Route path="/home" component={Home}></Route>
<Route path="/pricing" component={Pricing}></Route>
<Route path="/about" component={About}></Route>
<AuthedRoute path="/my-settings" component={Settings}></AuthedRoute>
<UnauthedRoute path="/sign-in" component={SignIn}></UnauthedRoute>
</div>
</Router>
/my-inbox
vs /my-inbox/message1234