ReactJS: Protected Routes Implementation in ReactJS
Protected Routes are routes that can only be accessed if a condition is met(usually, if user is properly authenticated). It returns a Route that either renders a component or redirects a user to another route based on a set condition. We will use this method if we want to separate between specific user and public user in accessing pages in our website by using ReactJS platform.
Step-by-step example to use this protected routes method
I have created some pages as a sample in implementing Protected Routes which can be accessed from URL below.
https://gitlab.com/irfaneffendiahmad/telkomathon-exercise-session19-learning-react/-/tree/master/src.
From many files in that link, some pages which are related to Protected Routes method are explained below.
1. Codes for App.js file in src folder
import React from 'react';
import { BrowserRouter, Switch, Route } from 'react-router-dom';
import { Helmet } from 'react-helmet';
import 'bootstrap/dist/css/bootstrap.min.css';
import './App.css';
import Navbar from './components/navbar';
import Home from './pages/AboutMe';
import ReactExample from './pages/ReactExample';
import Hooks1 from './pages/Hooks1';
import Hooks2 from './pages/Hooks2';
import Hooks3 from './pages/Hooks3';
import Hooks4 from './pages/Hooks4';
import Book from './pages/Book';
import Contributor from './pages/Contributor';
import Login from './pages/LoginPage';
import Register from './pages/Register';
import EmailFeedback from './pages/EmailFeedback';
import ProtectedRoute from './components/ProtectedRoute';
import { NotificationContainer } from 'react-notifications';
import 'react-notifications/lib/notifications.css';
function App() {
return (
<BrowserRouter>
<Helmet>
<title>Learning React</title>
</Helmet>
<Navbar />
<Switch>
<Route exact path="/" component={Home} />
<ProtectedRoute path="/ReactExample" component={ReactExample} />
<Route path="/Hooks1" component={Hooks1} />
<Route path="/Hooks2" component={Hooks2} />
<Route path="/Hooks3" component={Hooks3} />
<Route path="/Hooks4" component={Hooks4} />
<Route path="/Book" component={Book} />
<ProtectedRoute path="/Contributor" component={Contributor} />
<Route path="/EmailFeedback" component={EmailFeedback} />
<Route path="/LoginPage" component={Login} />
<Route path="/Register" component={Register} />
</Switch>
<NotificationContainer />
</BrowserRouter>
);
}
export default App;
2. Codes for ProtectedRoute.js file in components folder
import React from 'react';
import { Redirect, Route } from 'react-router-dom';
import { connect } from 'react-redux';
import { NotificationManager} from 'react-notifications';
const ProtectedRoute = ({ isAuth, component: Component, ...rest }) => {
return (
<Route
{...rest}
render={routeProps => {
if(isAuth) {
return <Component {...routeProps} />
} else {
NotificationManager.error('You are not logged in yet','',1000);
return (
<Redirect to="/" />
)
}
}}
/>
);
};
const mapStateToProps = (state) => ({
isAuth: state.auth.isAuthenticated
});
export default connect (mapStateToProps)(ProtectedRoute);
3. Codes for reducer.js file in redux/authentication folder
import { LOG_IN, LOG_OUT } from './actionTypes';
import { NotificationManager} from 'react-notifications';
const initialState = {
// isAuthenticated: false,
isAuthenticated: localStorage.getItem("keepLogin"),// Activate login after page refresh
};
const authReducer = (state = initialState, action) => {
if (action.type === LOG_IN) {
NotificationManager.success('You are logged in','',1000);
return {
...state,
isAuthenticated: true,
}
} else if (action.type === LOG_OUT) {
NotificationManager.warning('You have logged out successfully','',1000);
return {
...state,
isAuthenticated: false,
}
}
return state;
};
export default authReducer;
4. Codes for action.js file in redux/authentication folder
import { LOG_IN, LOG_OUT } from './actionTypes';
export const logInAction = {
type: LOG_IN,
};
export const logOutAction = {
type: LOG_OUT,
};
5. Codes for actionTypes.js file in redux/authentication folder
export const LOG_IN = 'LOG_IN';
export const LOG_OUT = 'LOG_OUT';
6. Codes for LoginPage.js file in pages folder
import React, { useState } from 'react';
import { Card } from 'react-bootstrap';
import { connect } from 'react-redux';
import { logInAction, logOutAction } from '../redux/authentication/actions';
import { useHistory } from 'react-router-dom';
import qs from 'qs';
import axios from 'axios';
const Login = (props) => {
// -------
const [signInData, setSignInData] = useState({
email: '',
password: ''
});
const handleChangeSignIn = (e) => {
setSignInData({
...signInData,
[e.target.name] : e.target.value
})
}
// -------
// -------
const [data, setData] = useState({});
const handleSubmitSignIn = (e) => {
e.preventDefault();
axios({
method: 'post',
url: 'https://reqres.in/api/register',
data: qs.stringify({
email: signInData.email,
password: signInData.password,
}),
headers: {
'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
}
}).then((response) => {
console.log('response =>', response.data.token);
setData(response.data.token);
if (data.token !== null) {
localStorage.setItem('keepLogin', JSON.stringify (response.data.token)); // Keep login while page refresh
handleClick();
} else {
console.log('response error', response.data.token);
}
});
}
const { isLogin, logInFunc, logOutFunc } = props;
const history = useHistory();
// console.log('props login page =>', props);
const handleClick = () => {
if (isLogin) {
logOutFunc();
history.push('/');
} else {
logInFunc();
history.push('/ReactExample');
}
}
// -------
// -------
const handleSignOut = () => {
logOutFunc();
history.push('/');
localStorage.clear();
}
// -------
return (
<center>
<Card style={{ width: '22rem' }}>
<Card.Body>
<form>
<div className="App">
<span style={{color: 'black'}}>{isLogin ? 'You are logged in' : null}</span>
<h1 style={{backgroundColor: '#D4EFDF'}}>{isLogin ? null : 'Login'}</h1>
</div>
<div className="form-group" style={{textAlign: 'left'}}>
<label>{isLogin ? null : 'Email address'}</label>
<input
type={isLogin ? 'hidden' : 'email'}
name="email" // Auth Key
className="form-control"
placeholder="eve.holt@reqres.in"
onChange={handleChangeSignIn}
/>
</div>
<div className="form-group" style={{textAlign: 'left'}}>
<label>{isLogin ? null : 'Password'}</label>
<input
type={isLogin ? 'hidden' : 'password'}
name="password" // Auth Key
className="form-control"
placeholder="pistol"
onChange={handleChangeSignIn}
/>
</div>
{/* email: eve.holt@reqres.in */}
{/* password: pistol */}
<button
onClick={isLogin ? handleSignOut : handleSubmitSignIn}
type="submit"
className="btn btn-primary btn-block">
{isLogin ? 'Logout' : 'Login'}
</button>
<p className="forgot-password text-right">
<a href="/">{isLogin ? null : 'Forgot password?'}</a>
</p>
</form>
</Card.Body>
</Card>
</center>
);
};
const mapStateToProps = (state) => ({
isLogin: state.auth.isAuthenticated
});
const mapDispatchToProps = (dispatch) => ({
logInFunc: () => dispatch(logInAction),
logOutFunc: () => dispatch(logOutAction)
});
export default connect(mapStateToProps, mapDispatchToProps)(Login);
From all of codes above the pages will be displayed like this link:
Easy enough to be implemented and enhanced. Hopefully this article help you to configure Protected Routes in your ReactJS website.
Comments
Post a Comment