DEV Community

Coder
Coder

Posted on

React - Role Based Authorization Tutorial with Example

Have you ever been in a situation where you wanted to control the access to certain components or routes in your React project based on user roles? This is where role-based authorization comes into play. In this tutorial, we will walk you through the process of implementing role-based authorization in your React application with an example.

What is Role-Based Authorization?

Role-based authorization is a security model that enables access control to resources based on the roles assigned to users. In simple terms, users with different roles will have different levels of access to resources such as components or routes in an application.

For example, in an e-commerce application, a customer with a guest role may only have access to the homepage and product listing page. On the other hand, an admin with an admin role may have access to the dashboard and the ability to add, edit, or delete products.

Setting up the Project

Before we dive into the implementation, let's set up a new React project using Create React App. To do this, run the following command in your terminal:

npx create-react-app react-role-based-auth
Enter fullscreen mode Exit fullscreen mode

Once the project is created, navigate to the project directory by running the following command in your terminal:

cd react-role-based-auth
Enter fullscreen mode Exit fullscreen mode

Creating User Roles

In this example, we will create two user roles - admin and guest. Create a new file called roles.js in the src directory and add the following code:

export const ROLES = {
  ADMIN: "admin",
  GUEST: "guest"
}
Enter fullscreen mode Exit fullscreen mode

In this code, we are creating two constants ADMIN and GUEST which represent the roles for our users.

Creating the Routes

Next, let's create some routes for our application. We will create three routes - homepage, dashboard, and products. Create a new file called Routes.js in the src directory and add the following code:

import React from "react";
import { Route, Redirect } from "react-router-dom";
import { ROLES } from "./roles";

export const PrivateRoute = ({ component: Component, role, ...rest }) => (
  <Route
    {...rest}
    render={(props) =>
      localStorage.getItem("auth-token") && role === ROLES.ADMIN ? (
        <Component {...props} />
      ) : (
        <Redirect to={{ pathname: "/", state: { from: props.location } }} />
      )
    }
  />
);

export const PublicRoute = ({ component: Component, ...rest }) => (
  <Route {...rest} render={(props) => <Component {...props} />} />
);
Enter fullscreen mode Exit fullscreen mode

In this code, we are creating two components - PrivateRoute and PublicRoute. The PrivateRoute component is used to protect routes that require authentication and only allow users with the admin role to access them. The PublicRoute component is used for routes that do not require authentication.

Implementing the Authentication

To simulate authentication, we will create a simple login form. Create a new file called LoginPage.js in the src directory and add the following code:

import React, { useState } from "react";

const LoginPage = ({ setUser }) => {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");

  const handleLogin = () => {
    // Simulating authentication
    if (username === "admin" && password === "admin") {
      localStorage.setItem("auth-token", "admin-token");
      setUser({ role: "admin" });
    } else if (username === "guest" && password === "guest") {
      localStorage.setItem("auth-token", "guest-token");
      setUser({ role: "guest" });
    }
  };

  return (
    <div>
      <h2>Login Page</h2>
      <div>
        <label>
          Username:
          <input
            type="text"
            value={username}
            onChange={(e) => setUsername(e.target.value)}
          />
        </label>
      </div>
      <div>
        <label>
          Password:
          <input
            type="password"
            value={password}
            onChange={(e) => setPassword(e.target.value)}
          />
        </label>
      </div>
      <div>
        <button onClick={handleLogin}>Login</button>
      </div>
    </div>
  );
};

export default LoginPage;
Enter fullscreen mode Exit fullscreen mode

In this code, we are creating a simple login form with username and password fields. We are also simulating authentication by storing the user's role in local storage.

Displaying the User Role

To display the user's role, we will create a new component called ProfilePage. Create a new file called ProfilePage.js in the src directory and add the following code:

import React from "react";

const ProfilePage = ({ role }) => {
  return (
    <div>
      <h2>Profile Page</h2>
      <p>You are logged in as: {role}</p>
    </div>
  );
};

export default ProfilePage;
Enter fullscreen mode Exit fullscreen mode

In this code, we are simply displaying the user's role.

Implementing the Routes

Now that we have our authentication and routes set up, let's implement them in our application. Open the App.js file and replace the default code with the following:

import React, { useState } from "react";
import { BrowserRouter, Switch } from "react-router-dom";
import { PrivateRoute, PublicRoute } from "./Routes";
import { ROLES } from "./roles";
import LoginPage from "./LoginPage";
import ProfilePage from "./ProfilePage";

const App = () => {
  const [user, setUser] = useState({});

  return (
    <BrowserRouter>
      <Switch>
        <PublicRoute exact path="/" component={LoginPage} />
        <PrivateRoute
          path="/dashboard"
          component={() => (
            <ProfilePage role={user.role} />
          )}
          role={ROLES.ADMIN}
        />
        <PublicRoute
          path="/products"
          component={() => (
            <ProfilePage role={user.role} />
          )}
        />
      </Switch>
    </BrowserRouter>
  );
};

export default App;
Enter fullscreen mode Exit fullscreen mode

In this code, we are using the BrowserRouter and Switch components from react-router-dom to define our routes. We are also using the PrivateRoute and PublicRoute components to protect our routes.

The PrivateRoute component is used for the /dashboard route, which requires authentication and only allows users with the admin role to access it. The PublicRoute component is used for the /products route, which does not require authentication.

Testing the Application

To test the application, run the following command in your terminal:

npm start
Enter fullscreen mode Exit fullscreen mode

This will start the development server and open your default browser. You should see the login page.

Enter admin as the username and admin as the password. This will log you in as an admin user and redirect you to the dashboard page.

Enter guest as the username and guest as the password. This will log you in as a guest user and redirect you to the products page.

If you try to access the dashboard page as a guest user, you will be redirected back to the login page.

Conclusion

In this tutorial, we walked you through the process of implementing role-based authorization in your React application. We created two user roles, created routes, implemented authentication, and tested the application.

Role-based authorization is an important security feature in any application, and it can be easily implemented in your React project using the techniques we've covered in this tutorial.

Top comments (0)