How to implement authorization with role based accessibility in Next js?
Published: 2024-06-03 06:45:07

To implement authorization and role-based protected routes in Next.js, you can follow these steps:

1. **Set Up Authentication:**
   Use an authentication library like `next-auth` for user authentication. This will handle user sign-in, sign-out, and session management.

2. **Create Roles:**
   Define user roles (e.g., admin, user, editor) and assign them to users upon registration or within your user database.

3. **Protect Routes Based on Roles:**
   Use a higher-order component (HOC) or middleware to protect your routes based on user roles.

### Step-by-Step Implementation

#### 1. Install NextAuth.js

First, install `next-auth`:

```bash
npm install next-auth
```

#### 2. Configure NextAuth.js

Create a file named `[...nextauth].js` in the `pages/api/auth` directory:

```javascript
import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';

export default NextAuth({
  providers: [
    Providers.Credentials({
      name: 'Credentials',
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' },
      },
      authorize: async (credentials) => {
        const user = await fetchUserFromDatabase(credentials.email, credentials.password);
        if (user) {
          return user;
        } else {
          return null;
        }
      },
    }),
  ],
  callbacks: {
    async session(session, user) {
      session.user.role = user.role;  // Add role to session
      return session;
    },
    async jwt(token, user) {
      if (user) {
        token.role = user.role;
      }
      return token;
    },
  },
});

async function fetchUserFromDatabase(email, password) {
  // Implement user fetching logic here
  return { id: 1, name: 'John Doe', email, role: 'admin' }; // Example user
}
```

#### 3. Create Protected Route HOC

Create a higher-order component (HOC) to protect your routes based on user roles:

```javascript
import { useSession, getSession } from 'next-auth/client';
import { useRouter } from 'next/router';
import { useEffect } from 'react';

const withAuth = (Component, allowedRoles) => {
  return (props) => {
    const [session, loading] = useSession();
    const router = useRouter();

    useEffect(() => {
      if (!loading) {
        if (!session) {
          router.push('/api/auth/signin');
        } else if (!allowedRoles.includes(session.user.role)) {
          router.push('/unauthorized');
        }
      }
    }, [loading, session, router]);

    if (loading || !session) {
      return <p>Loading...</p>;
    }

    return <Component {...props} />;
  };
};

export default withAuth;
```

#### 4. Protect Your Pages

Wrap your pages with the `withAuth` HOC to protect them based on user roles:

```javascript
import withAuth from '../hoc/withAuth';

const AdminPage = () => {
  return <div>Admin Content</div>;
};

export default withAuth(AdminPage, ['admin']);
```

#### 5. Create an Unauthorized Page

Create a page to show when the user is unauthorized:

```javascript
// pages/unauthorized.js
const Unauthorized = () => {
  return <h1>Unauthorized - You do not have access to this page</h1>;
};

export default Unauthorized;
```

### Summary

1. **Install and configure `next-auth`** for authentication.
2. **Define user roles** and include them in the session.
3. **Create a higher-order component (HOC)** to protect routes based on roles.
4. **Wrap your pages** with the HOC to enforce role-based access control.
5. **Create an unauthorized page** to handle access denial.

This setup provides a robust way to manage authentication and authorization in a Next.js application, allowing you to protect routes based on user roles effectively.

Disclaimer: This content is generated by AI.