Public , Private and Restricted Route using React Router
In the tutorial we are going to look at, how can we make private, public and restricted route using react router.
Suppose we have an app, which has a Login page, Home page and an About page. Have a look at App.js file fo the application which has simple route for mentioned pages.
Now as you can notice here user can access '/','/home','/login' and '/about' route anytime without any restriction. But in the real world scenario we should not allow a user to Application Home page until and unless user is verified with his/her credentials. For that we need to restrict '/home' and '/login' route.
So scenario is like below :
Home page : A private and restricted route
Login page : A public and restricted route
About page : A public and non-restricted route
Okay, now lets change the above implementation to achieve our requirement. I am creating a login checker function, which will check a session storage key to validate if user is logged in.
Next, we will create Private and Public route wrappers.
PrivateRoute.js
PublicRoute.js
Let's update the App.js file now :
Accordingly we need to write login and logout functions in respective components to handle login/logout actions.
Here is the Login component, which handles the LOGIN action :
In logged out state session storage does not gave 'login key', refer screenshots below
Home component, which handles the LOGOUT action:
About component, which does not depend on user's logged in state.
About page is not effected with login status, as it is a Public and non-restricted route
Suppose we have an app, which has a Login page, Home page and an About page. Have a look at App.js file fo the application which has simple route for mentioned pages.
import React from 'react'; import Login from './components/Login' import Dashboard from './components/Dashboard' import About from './components/About' import { BrowserRouter,Switch,Route } from 'react-router-dom' const App = () => { return ( <BrowserRouter> <Switch> <Route path="/home" exact component={Dashboard} /> <Route path="/login" exact component={Login} /> <Route path="/about" component={About} /> <Route path="/" exact component={Login} /> </Switch> </BrowserRouter> ); } export default App;
Now as you can notice here user can access '/','/home','/login' and '/about' route anytime without any restriction. But in the real world scenario we should not allow a user to Application Home page until and unless user is verified with his/her credentials. For that we need to restrict '/home' and '/login' route.
- If user is already logged in application should not allow him/her to stay '/login' page, rather it should automatically redirect the user to the '/home' route.
- In the same way, if user is not logged in application should not allow user to access '/home' route, it should redirect to '/login' route.
- There is another page '/about', which can be accessed whether the user is logged in or out.
So scenario is like below :
Home page : A private and restricted route
Login page : A public and restricted route
About page : A public and non-restricted route
Okay, now lets change the above implementation to achieve our requirement. I am creating a login checker function, which will check a session storage key to validate if user is logged in.
export const isLoggedIn = () =>{ if(sessionStorage.login === 'true'){ return true }else{ return false } }
Next, we will create Private and Public route wrappers.
PrivateRoute.js
import React from 'react'; import { Route,Redirect } from 'react-router-dom' import {isLoggedIn} from '../util' const PrivateRoute = ({component :Component,...rest}) =>{ return( <Route {...rest} render={props=>( isLoggedIn() ? <Component {...props} /> : <Redirect to="/login" /> )} /> ) } export default PrivateRoute
PublicRoute.js
import React from 'react'; import { Route,Redirect } from 'react-router-dom' import {isLoggedIn} from '../util' const PublicRoute = ({component :Component,isRestricted,...rest}) =>{ return( <Route {...rest} render={props=>( (isLoggedIn() && isRestricted) ? <Redirect to="/home" /> : <Component {...props} /> )} /> ) } export default PublicRoute
Let's update the App.js file now :
import React from 'react'; import Login from './components/Login' import Dashboard from './components/Dashboard' import About from './components/About' import { BrowserRouter,Switch } from 'react-router-dom' import PublicRoute from './routes/PublicRoute' import PrivateRoute from './routes/PrivateRoute' const App = () => { return ( <BrowserRouter> <Switch> <PrivateRoute path="/home" exact component={Dashboard} /> <PublicRoute isRestricted={true} path="/login" exact component={Login} /> <PublicRoute isRestricted={true} path="/" exact component={Login} /> <PublicRoute isRestricted={false} path="/about" component={About} /> </Switch> </BrowserRouter> ); } export default App;
Accordingly we need to write login and logout functions in respective components to handle login/logout actions.
Here is the Login component, which handles the LOGIN action :
import React, { Fragment, useState } from 'react'; import { useHistory } from "react-router-dom"; const Login = () =>{ const [userName,setUserName] = useState('') const [pwd,setPwd] = useState('') const [error,setError] = useState(false) const history = useHistory(); const login = () => {
//In original scenario an endpoint should be called to validate user
if(userName === "test" && pwd === "test"){
sessionStorage.setItem('login',true)
history.push("/home");
}else{
setError(true)
setTimeout(()=>{
setError(false)
},5000)
}
}
const onChangeField = e => {
switch (e.target.name) {
case 'username':
setUserName(e.target.value)
break;
case 'password':
setPwd(e.target.value)
break;
default:
break;
}
}
return(
<Fragment>
<span>Username : </span>
<input onChange={onChangeField} name="username" type="text" />
<span>Password : </span>
<input onChange={onChangeField} name="password" type="password" />
<button onClick={login}>Login</button>
{error && <span style={{
display:'block',
color:'red',
fontSize:22
}}>Invalid Credentials</span>}
</Fragment>
)
}
export default Login
In logged out state session storage does not gave 'login key', refer screenshots below
Home component, which handles the LOGOUT action:
import React from 'react'; import { useHistory } from 'react-router-dom' const Dashboard = () =>{ const history = useHistory() const logout = e =>{ e.preventDefault() sessionStorage.removeItem('login') history.push('/login') } return( <div> <span>You are loggin in</span> <button onClick={logout}>Logout</button> </div> ) } export default Dashboard
About component, which does not depend on user's logged in state.
import React from 'react'; const About = () =>{ return( <span>Sample About page</span> ) } export default About
About page is not effected with login status, as it is a Public and non-restricted route





Nice Blog.
ReplyDeleteI've gone through all the details that you mentioned in the blog along with the sample codes you mentioned for every small and big changes. I believe that every newbie could also understand the concept of using react native after going through this blog.
I was looking forward to hire dedicated react native developer and got your blog.
Thanks for sharing such a great blog.
Synsoft Global