이번 프로젝트의 경우, 한명의 관리자가 SUPER_ADMIN, OP_ADMIN, CS_ADMIN 중 한개의 역할만 가지는 경우를 처리하였는데, 만약 역할을 하나만 가지되 READ_PRODUCT, CREATE_PRODUCT 와 같은 권한을 여러개 가지는 경우에는, 이를 프로젝트에서 어떻게 다룰지 생각해보았다.
1. enum 클래스에서 Set<> 을 통해 관리
@Getter
@RequiredArgsConstructor
public enum Role {
SUPER_ADMIN(Set.of(
Permission.USER_READ,
Permission.USER_WRITE,
Permission.ITEM_READ,
Permission.ITEM_WRITE,
Permission.ORDER_READ,
Permission.ORDER_MANAGE
)),
OP_ADMIN(Set.of(
Permission.USER_READ,
Permission.ITEM_READ,
Permission.ORDER_READ
));
private final Set<Permission> permissions;
}
첫번째 방법은 위와 같이 하나의 역할에 set을 통해 여러개의 권한을 저장하여 관리하는 방식이다. set으로 관리하는 이유는 권한은 중복될 수 없으며, 저장되는 순서가 의미 없기 때문이다.
이 방법의 경우, 권한과 관련한 별도의 테이블을 생성하지 않아도 된다는 장점이 존재하지만, 하나의 역할에 저장되는 권한이 고정되기 때문에 특정 관리자에게만 권한을 추가할 수 없는 문제와 같이 권한 변경 정책을 유연하게 처리할 수 없다는 단점이 존재한다.
2. 관리자, 역할, 권한, 역할_권한, 관리자_역할 테이블 생성
두번째 방법은 역할과 권한 테이블을 추가로 생성하고, 관리자-역할, 역할-권한 사이의 N:M 관계를 해결하기 위한 중간 테이블을 2개 더 생성하여 관리하는 방법이다.
이 방법의 경우에는 권한 정책이 변경되는 상황에 대하여 유연하게 대처할 수 있지만, 추가적으로 여러개의 테이블을 만들어 관리해야 하고, 각 테이블들이 fk 를 통해 복잡하게 연결되어 있기 때문에 데이터 정합성을 관리하기 힘들다는 단점이 존재한다.
3. 관리자, 역할, 역할_권한 테이블 생성 / 권한은 enum 타입으로 관리
마지막 방법은 역할 테이블을 생성하여 관리자와 ManyToOne 관계로 연결하고 (관리자가 Many), 권한은 enum 타입으로 관리,. 역할_권한 테이블 에서는 역할 id 값과 권한 이름의 String 값을 하나로 묶어서 복합 pk로 관리하는 방법이다.
이와 같은 방법은 첫번째 방법보다 권한 정책 변경에 유연하고, 두번째 방법보다 테이블, 데이터 정합성 관리 등이 쉬워서 균형 잡힌 방법이라고 생각된다.
아래는 예시

Role 테이블
| id | name |
| 1 | SUPER_ADMIN |
| 2 | OP_ADMIN |
| 3 | CS_ADMIN |
Administrator 테이블
| id | password | role_id | |
| 1 | example@example1.com | 12345 | 1 |
| 2 | example@example2.com | 67890 | 3 |
Role_Permission 테이블
| role_id | permission |
| 1 | USER_READ |
| 1 | USER_WRITE |
| 2 | ITEM_READ |
| 2 | ITEM_WRITE |
| 3 | ORDER_MANAGE |
Permission enum 클래스
public enum Permission {
USER_READ,
USER_WRITE,
ITEM_READ,
ITEM_WRITE,
ORDER_READ,
ORDER_MANAGE
}
Administrator 엔티티 클래스
@Entity
@Table(name = "admins")
public class Admin {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "role_id", nullable = false)
private Role role;
}
'트러블슈팅' 카테고리의 다른 글
| 클라우드 아키텍쳐 설계 & 배포 (0) | 2026.02.03 |
|---|---|
| Spring 코드 개선 (0) | 2026.01.27 |
| 커맨드 라인 러너 (commandLine Runner) (0) | 2026.01.20 |
| 스케줄, 일정, 유저 관리 앱 Postman (0) | 2026.01.12 |
| 스케줄, 일정, 유저 관리 앱 상세 API (0) | 2026.01.12 |