Role-Based Authorization and Authentication in React with Auth Handlers — Specific role-based and anonymous auth pages
Role-based authorization and authentication are essential for securing React applications by controlling access to different parts of the application based on user roles. We’ll use authentication handlers to manage authentication and authorization logic.
.Net core similar implementation https://medium.com/@siva.veeravarapu/role-based-authorization-in-net-core-a-beginners-guide-with-code-snippets-b952e5b952f7
Embark on a journey of continuous learning and exploration with DotNet-FullStack-Dev. Uncover more by visiting our https://dotnet-fullstack-dev.blogspot.com reach out for further information.
Step 1: Set up Authentication Context
Create an Authentication Context to manage user authentication state and provide authentication methods to the components.
AuthContext.js:
import React, { createContext, useContext, useState } from 'react';
const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const login = (userData) => {
// Implement login logic here (e.g., API call)
setUser(userData);
};
const logout = () => {
// Implement logout logic here
setUser(null);
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
export const useAuth = () => useContext(AuthContext);
Step 2: Implement Authentication Components
Create components for login, logout, and protected routes.
Login.js:
import React, { useState } from 'react';
import { useAuth } from './AuthContext';
const Login = () => {
const { login } = useAuth();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const handleLogin = () => {
// Implement login logic (e.g., call login method from AuthContext)
login({ username, password });
};
return (
<div>
<input type="text" value={username} onChange={(e) => setUsername(e.target.value)} />
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} />
<button onClick={handleLogin}>Login</button>
</div>
);
};
export default Login;
Logout.js:
import React from 'react';
import { useAuth } from './AuthContext';
const Logout = () => {
const { logout } = useAuth();
const handleLogout = () => {
// Implement logout logic (e.g., call logout method from AuthContext)
logout();
};
return (
<div>
<button onClick={handleLogout}>Logout</button>
</div>
);
};
export default Logout;
ProtectedRoute.js:
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { useAuth } from './AuthContext';
const ProtectedRoute = ({ component: Component, roles, ...rest }) => {
const { user } = useAuth();
return (
<Route {...rest} render={(props) => {
if (!user) {
return <Redirect to='/login' />;
}
if (roles && !roles.includes(user.role)) {
return <Redirect to='/' />;
}
return <Component {...props} />;
}} />
);
};
export default ProtectedRoute;
Step 3: Use Authentication Components
Use the authentication components in your application routes.
App.js:
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { AuthProvider } from './AuthContext';
import Login from './Login';
import Logout from './Logout';
import ProtectedRoute from './ProtectedRoute';
import Home from './Home';
import AdminDashboard from './AdminDashboard';
const App = () => {
return (
<AuthProvider>
<Router>
<Switch>
<Route path='/login' component={Login} />
<Route path='/logout' component={Logout} />
<ProtectedRoute path='/admin' component={AdminDashboard} roles={['admin']} />
<ProtectedRoute path='/' component={Home} />
</Switch>
</Router>
</AuthProvider>
);
};
export default App;
About and Contact pages with role-based access control in a React application, we’ll extend with additional components and routes.
Implement About and Contact Components
About.js:
import React from 'react';
const About = () => {
return (
<div>
<h1>About Us</h1>
<p>Welcome to our website!</p>
</div>
);
};
export default About;
Contact.js:
import React from 'react';
const Contact = () => {
return (
<div>
<h1>Contact Us</h1>
<p>You can reach us via email or phone.</p>
</div>
);
};
export default Contact;
Update ProtectedRoute Component
ProtectedRoute.js:
import React from 'react';
import { Route, Redirect } from 'react-router-dom';
import { useAuth } from './AuthContext';
const ProtectedRoute = ({ component: Component, roles, ...rest }) => {
const { user } = useAuth();
return (
<Route {...rest} render={(props) => {
if (!user) {
return <Redirect to='/login' />;
}
if (roles && !roles.includes(user.role)) {
return <Redirect to='/' />;
}
return <Component {...props} />;
}} />
);
};
export default ProtectedRoute;
Update App Component and Routing
App.js:
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { AuthProvider } from './AuthContext';
import Login from './Login';
import Logout from './Logout';
import ProtectedRoute from './ProtectedRoute';
import Home from './Home';
import AdminDashboard from './AdminDashboard';
import About from './About';
import Contact from './Contact';
const App = () => {
return (
<AuthProvider>
<Router>
<Switch>
<Route path='/login' component={Login} />
<Route path='/logout' component={Logout} />
<ProtectedRoute path='/admin' component={AdminDashboard} roles={['admin']} />
<ProtectedRoute path='/about' component={About} roles={['user', 'admin']} />
<Route path='/contact' component={Contact} />
<ProtectedRoute path='/' component={Home} />
</Switch>
</Router>
</AuthProvider>
);
};
export default App;
Conclusion
By following this guide, you can implement role-based authorization and authentication in React functional components using authentication handlers. This approach provides a flexible and scalable solution for securing your React applications. Experiment with different authentication and authorization strategies to meet your application’s specific requirements.
This approach ensures role-based access control for the About page and unrestricted access to the Contact page. Adjust the roles and permissions according to your application’s requirements.