Role-Based Authorization and Authentication in React with Auth Handlers — Specific role-based and anonymous auth pages

DotNet Full Stack Dev
4 min readApr 12, 2024

--

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.

--

--

DotNet Full Stack Dev
DotNet Full Stack Dev

Written by DotNet Full Stack Dev

Join me to master .NET Full Stack Development & boost your skills by 1% daily with insights, examples, and techniques! https://dotnet-fullstack-dev.blogspot.com

No responses yet