How to Create a Protected Route with react-router-dom?
If you are working with ReactJS and using react-router-dom for routing, you may encounter the need to create a protected route. A protected route ensures that only authenticated users can access certain pages or components within your application.
Why Create a Protected Route?
Creating a protected route is essential for security and authorization purposes. For example, if your application has a dashboard page that should only be accessible to authenticated users, you can implement a protected route to restrict unauthorized access.
Using react-router-dom to Create Protected Routes
To create a protected route with react-router-dom, you can leverage the Route
component provided by the library. Here's a step-by-step guide on how to do it:
Step 1: Set Up Context
In this example, we will be using Context API for authentication. Start by creating a new file called context.js
and defining the necessary context and provider components:
import React, { Component, createContext } from "react";
import axios from "axios";
export const AuthContext = createContext();
export class AuthProvider extends Component {
state = {
isAuthenticated: false,
user: null,
error: null
};
componentDidMount() {
// Check if user is already authenticated
const storedUser = localStorage.getItem("user");
if (storedUser) {
this.setState({
isAuthenticated: true,
user: JSON.parse(storedUser)
});
}
}
login = async (credentials) => {
// Perform authentication logic (e.g., call an API endpoint)
try {
const response = await axios.post("/api/login", credentials);
// Store user data locally
localStorage.setItem("user", JSON.stringify(response.data));
// Update state
this.setState({
isAuthenticated: true,
user: response.data,
error: null
});
} catch (error) {
this.setState({
isAuthenticated: false,
user: null,
error: "Invalid credentials. Please try again."
});
}
};
logout = () => {
// Clear user data from local storage
localStorage.removeItem("user");
// Update state
this.setState({
isAuthenticated: false,
user: null,
error: null
});
};
render() {
const { isAuthenticated, user, error } = this.state;
return (
{this.props.children}
);
}
}
In this code snippet, we define the AuthContext
and AuthProvider
components. The AuthProvider
component holds the state related to authentication and provides the login and logout methods to update the state.
Step 2: Create Login Component
Next, create a Login
component where users can enter their credentials and authenticate themselves. Here's an example implementation:
import React, { useContext, useState } from "react";
import { AuthContext } from "./context";
function Login() {
const { login, error } = useContext(AuthContext);
const [credentials, setCredentials] = useState({
email: "",
password: ""
});
const handleChange = (e) => {
setCredentials({
...credentials,
[e.target.name]: e.target.value
});
};
const handleSubmit = (e) => {
e.preventDefault();
login(credentials);
};
return (
{error && {error}
}
);
}
export default Login;
In this code snippet, we use the useContext
hook to access the login
function from the AuthContext
. The login
function is called when the form is submitted, and it takes care of authenticating the user.
Step 3: Create Protected Route
Create a protected route component that restricts access to authenticated users. You can define this component as follows:
import React, { useContext } from "react";
import { Route, Redirect } from "react-router-dom";
import { AuthContext } from "./context";
function ProtectedRoute({ component: Component, ...rest }) {
const { isAuthenticated } = useContext(AuthContext);
return (
isAuthenticated ? :
}
/>
);
}
export default ProtectedRoute;
In this code snippet, we use the useContext
hook to access the isAuthenticated
state from the AuthContext
. If the user is authenticated, the component specified in the component
prop is rendered. Otherwise, the user is redirected to the login page.
Step 4: Set Up Routes
Finally, set up your routes in the main component of your application, making use of the ProtectedRoute
component to restrict access to certain pages. Here's an example:
import React from "react";
import { BrowserRouter as Router, Switch } from "react-router-dom";
import { AuthProvider } from "./context";
import ProtectedRoute from "./ProtectedRoute";
import Dashboard from "./Dashboard";
import Profile from "./Profile";
import Login from "./Login";
function App() {
return (
);
}
export default App;
In this code snippet, we use the ProtectedRoute
component to protect the /dashboard
and /profile
routes. Only authenticated users can view these pages, and if a user is not authenticated, they are redirected to the login page.
Conclusion
By leveraging the capabilities of react-router-dom and Context API, you can easily create protected routes in your React application. This ensures better security and authorization, allowing only authenticated users to access certain pages or components.