코딩 공부

Next.js에서 사용자 역할(Role-Based Access Control, RBAC)을 활용한 권한 관리

새혀니 2025. 3. 4. 20:50

 

  • RBAC(역할 기반 접근 제어)의 개념과 필요성
  • Next.js 서버 액션을 활용한 사용자 역할 관리
  • 인증된 사용자만 특정 페이지에 접근하도록 구현하는 방법

app/actions.js (사용자 역할 기반 접근 제어)

'use server';

import jwt from 'jsonwebtoken';
import bcrypt from 'bcryptjs';

const users = [
  { id: 1, username: 'admin', password: bcrypt.hashSync('admin123', 10), role: 'admin' },
  { id: 2, username: 'user', password: bcrypt.hashSync('user123', 10), role: 'user' },
];

const SECRET_KEY = process.env.JWT_SECRET;

export async function loginUser(formData) {
  const username = formData.get('username');
  const password = formData.get('password');

  const user = users.find((u) => u.username === username);
  if (!user || !bcrypt.compareSync(password, user.password)) {
    return { error: '잘못된 로그인 정보' };
  }

  const token = jwt.sign({ id: user.id, username: user.username, role: user.role }, SECRET_KEY, {
    expiresIn: '1h',
  });

  return { token, role: user.role };
}

export async function verifyToken(token) {
  try {
    return jwt.verify(token, SECRET_KEY);
  } catch (error) {
    return null;
  }
}

 

app/page.js (RBAC 기반 로그인 UI)

import { loginUser } from './actions';
import { useState } from 'react';

export default function Home() {
  const [token, setToken] = useState('');
  const [role, setRole] = useState('');
  const [error, setError] = useState('');

  async function handleLogin(event) {
    event.preventDefault();
    const formData = new FormData(event.target);
    const response = await loginUser(formData);

    if (response.token) {
      setToken(response.token);
      setRole(response.role);
      setError('');
    } else {
      setError(response.error);
    }
  }

  return (
    <div>
      <h1>RBAC 기반 로그인</h1>
      <form onSubmit={handleLogin}>
        <input type="text" name="username" placeholder="아이디" required />
        <input type="password" name="password" placeholder="비밀번호" required />
        <button type="submit">로그인</button>
      </form>
      {error && <p style={{ color: 'red' }}>{error}</p>}
      {token && <p>토큰: {token}</p>}
      {role && <p>사용자 역할: {role}</p>}
      {role === 'admin' && <p>관리자 전용 콘텐츠</p>}
    </div>
  );
}

 

환경 변수 설정 파일: .env.local

JWT_SECRET=your-secret-key

 

RBAC를 활용하면 사용자 권한에 따라 페이지 접근을 제한할 수 있음