0626 백엔드 실무 심화 (6/N): 관리자 권한 설계와 접근 제어
✅ 1. 관리자 권한 설계란 무엇인가?
- 관리자 권한 설계는 관리자 페이지에서 “누가 어떤 기능을 볼 수 있고, 어떤 작업을 실행할 수 있는지”를 정하는 구조입니다.
- 단순히 로그인만 막는 것이 아니라, 관리자별 역할에 따라 조회, 수정, 삭제, 다운로드, 승인, 설정 변경 같은 권한을 나눠야 합니다.
- 고객 정보, 주문 정보, 상담 메모, 엑셀 다운로드, 사이트 설정 같은 기능은 민감도가 높기 때문에 권한 관리가 매우 중요합니다.
➕ 1-1. 권한 설계가 중요한 이유
-
개인정보 보호
- 모든 관리자가 고객 전화번호, 상담 메모, 다운로드 파일을 볼 필요는 없습니다.
-
운영 사고 방지
- 실수로 상품을 삭제하거나 주문 상태를 변경하는 사고를 줄일 수 있습니다.
-
책임 추적
- 누가 언제 어떤 데이터를 수정했는지 기록할 수 있습니다.
-
업무 분리
- 상담 담당자, 개발자, 운영자, 대표 관리자 권한을 구분할 수 있습니다.
-
보안 강화
- 관리자 계정 하나가 유출되어도 피해 범위를 줄일 수 있습니다.
나쁜 구조:
관리자 로그인만 하면 모든 기능 사용 가능
좋은 구조:
관리자 역할별로 조회/수정/삭제/다운로드/설정 권한 분리
✅ 2. 인증과 인가의 차이
- 관리자 권한을 이해하려면 인증과 인가를 구분해야 합니다.
| 구분 | 의미 | 예시 |
|---|
| 인증 Authentication | 사용자가 누구인지 확인 | 관리자 로그인 |
| 인가 Authorization | 이 사용자가 이 기능을 쓸 수 있는지 확인 | 엑셀 다운로드 가능 여부 |
➕ 2-1. 실무 예시
관리자가 로그인 성공
↓
인증 완료
상담 목록 조회 요청
↓
이 관리자가 상담 목록을 볼 권한이 있는지 확인
↓
인가 확인
- 로그인했다고 해서 모든 기능을 사용할 수 있는 것은 아닙니다.
- 인증은 “누구인지”, 인가는 “무엇을 할 수 있는지”입니다.
✅ 3. 관리자 역할 설계
- 가장 단순한 방식은 역할을 기준으로 권한을 나누는 것입니다.
- 이를 보통 RBAC(Role-Based Access Control)이라고 합니다.
➕ 3-1. 역할 예시
| 역할 | 설명 |
|---|
SUPER_ADMIN | 전체 관리자 |
ADMIN | 일반 관리자 |
MANAGER | 상담/주문 담당자 |
MARKETER | 광고/유입 분석 담당자 |
VIEWER | 조회 전용 |
DEVELOPER | 개발/운영 담당자 |
➕ 3-2. 역할별 권한 예시
| 기능 | SUPER_ADMIN | ADMIN | MANAGER | MARKETER | VIEWER |
|---|
| 상담 목록 조회 | 가능 | 가능 | 가능 | 제한 | 가능 |
| 상담 상태 변경 | 가능 | 가능 | 가능 | 불가 | 불가 |
| 상담 메모 수정 | 가능 | 가능 | 가능 | 불가 | 불가 |
| 엑셀 다운로드 | 가능 | 가능 | 제한 | 제한 | 불가 |
| 상품 수정 | 가능 | 가능 | 불가 | 불가 | 불가 |
| 배너 수정 | 가능 | 가능 | 불가 | 가능 | 불가 |
| 관리자 계정 생성 | 가능 | 불가 | 불가 | 불가 | 불가 |
| 시스템 설정 변경 | 가능 | 불가 | 불가 | 불가 | 불가 |
- 처음에는 역할을 너무 많이 만들기보다 3~5개 정도로 시작하는 것이 좋습니다.
- 역할이 많아질수록 관리가 복잡해집니다.
✅ 4. 권한 단위 설계
- 역할만으로 부족한 경우 기능 단위 권한을 별도로 설계할 수 있습니다.
- 예를 들어
ADMIN이어도 엑셀 다운로드는 불가능하게 하거나, MANAGER에게 특정 상담 데이터만 보이게 할 수 있습니다.
➕ 4-1. 권한 코드 예시
consult:read
consult:update
consult:delete
consult:export
order:read
order:update
order:export
product:read
product:create
product:update
product:delete
banner:read
banner:update
admin:read
admin:create
admin:update
admin:delete
setting:read
setting:update
➕ 4-2. 권한 코드 설계 기준
리소스:행동 구조로 만든다.
- 이름은 짧고 명확하게 만든다.
- 조회, 생성, 수정, 삭제, 다운로드를 구분한다.
- 실제 API와 연결하기 쉽게 만든다.
- 프론트엔드 메뉴 표시에도 재사용할 수 있게 만든다.
resource:action
예시:
consult:read
consult:export
product:update
setting:update
✅ 5. RBAC와 Permission 기반 접근 제어
➕ 5-1. RBAC
- RBAC는 역할 기준으로 권한을 부여하는 방식입니다.
MANAGER 역할
↓
상담 조회 가능
상담 수정 가능
엑셀 다운로드 제한
상품 수정 불가
- 구현이 단순하고 이해하기 쉽습니다.
- 대부분의 작은 관리자 시스템은 RBAC만으로도 충분합니다.
➕ 5-2. Permission 기반
- Permission 기반은 역할보다 더 세밀하게 기능 권한을 부여하는 방식입니다.
사용자 A:
consult:read
consult:update
사용자 B:
consult:read
consult:export
product:update
- 유연하지만 관리가 복잡해질 수 있습니다.
- 권한이 많아지면 관리자 화면에서 권한 관리 UI도 필요합니다.
➕ 5-3. 실무 기준
초기:
역할 기반 RBAC로 시작
복잡해지면:
역할 + Permission 조합
대규모 조직:
부서, 담당 범위, 데이터 소유권까지 고려
- 1인 개발자 또는 작은 회사에서는 처음부터 너무 복잡한 권한 시스템을 만들 필요는 없습니다.
- 다만 백엔드에서 권한 검사는 반드시 해야 합니다.
✅ 6. 데이터 범위 권한
- 기능 권한이 있다고 해서 모든 데이터를 볼 수 있어야 하는 것은 아닙니다.
- 관리자는 본인 담당 데이터만 볼 수 있어야 하는 경우가 있습니다.
➕ 6-1. 데이터 범위 예시
| 범위 | 설명 |
|---|
| 전체 데이터 | 모든 상담/주문 조회 가능 |
| 본인 담당 데이터 | managerId가 본인인 데이터만 조회 |
| 소속 팀 데이터 | 같은 팀 데이터만 조회 |
| 특정 유입경로 데이터 | 네이버/당근 등 특정 source만 조회 |
| 조회 전용 데이터 | 수정 없이 보기만 가능 |
➕ 6-2. 상담 데이터 범위 예시
SUPER_ADMIN:
모든 상담 신청 조회 가능
MANAGER:
본인에게 배정된 상담 신청만 조회 가능
MARKETER:
개인정보 마스킹된 유입 통계만 조회 가능
VIEWER:
상담 목록 조회 가능, 전화번호 마스킹
- 데이터 범위 권한은 관리자 페이지에서 매우 중요합니다.
- 특히 개인정보가 포함된 데이터는 역할뿐 아니라 데이터 범위까지 고려해야 합니다.
✅ 7. Prisma 모델 설계 예시
➕ 7-1. Admin 모델
model Admin {
id Int @id @default(autoincrement())
email String @unique
passwordHash String
name String
role AdminRole
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
consults Consult[]
}
enum AdminRole {
SUPER_ADMIN
ADMIN
MANAGER
MARKETER
VIEWER
}
- 가장 단순한 구조는 Admin 테이블에 role을 직접 두는 방식입니다.
- 초기 서비스에서는 이 정도로 시작할 수 있습니다.
➕ 7-2. Permission까지 확장한 모델
model Admin {
id Int @id @default(autoincrement())
email String @unique
passwordHash String
name String
roleId Int
isActive Boolean @default(true)
role Role @relation(fields: [roleId], references: [id])
}
model Role {
id Int @id @default(autoincrement())
name String @unique
permissions RolePermission[]
admins Admin[]
}
model Permission {
id Int @id @default(autoincrement())
code String @unique
description String?
roles RolePermission[]
}
model RolePermission {
roleId Int
permissionId Int
role Role @relation(fields: [roleId], references: [id])
permission Permission @relation(fields: [permissionId], references: [id])
@@id([roleId, permissionId])
}
- 기능별 권한이 많아지면 이런 구조로 확장할 수 있습니다.
- 다만 초기에 과하게 만들면 개발 속도가 느려질 수 있습니다.
✅ 8. NestJS Guard
- NestJS에서는 Guard를 사용해 요청이 Controller에 도달하기 전에 인증과 권한을 검사할 수 있습니다.
- 로그인 여부 확인은
JwtAuthGuard, 역할 확인은 RolesGuard, 권한 확인은 PermissionsGuard처럼 나눌 수 있습니다.
➕ 8-1. 역할 Decorator 예시
export const ROLES_KEY = 'roles';
export const Roles = (...roles: AdminRole[]) =>
SetMetadata(ROLES_KEY, roles);
➕ 8-2. RolesGuard 예시
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<AdminRole[]>(
ROLES_KEY,
[context.getHandler(), context.getClass()],
);
if (!requiredRoles) {
return true;
}
const request = context.switchToHttp().getRequest();
const admin = request.user;
return requiredRoles.includes(admin.role);
}
}
- Controller에 필요한 역할을 지정하고 Guard에서 현재 사용자의 role을 검사합니다.
✅ 9. Controller에서 권한 적용하기
➕ 9-1. 상담 목록 조회
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(AdminRole.SUPER_ADMIN, AdminRole.ADMIN, AdminRole.MANAGER, AdminRole.VIEWER)
@Get('admin/consults')
async getConsults(@CurrentAdmin() admin: AdminPayload, @Query() query: SearchConsultDto) {
return this.consultService.searchConsults(admin, query);
}
➕ 9-2. 상담 상태 변경
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(AdminRole.SUPER_ADMIN, AdminRole.ADMIN, AdminRole.MANAGER)
@Patch('admin/consults/:id/status')
async updateConsultStatus(
@CurrentAdmin() admin: AdminPayload,
@Param('id') id: string,
@Body() dto: UpdateConsultStatusDto,
) {
return this.consultService.updateStatus(admin, Number(id), dto);
}
➕ 9-3. 엑셀 다운로드
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles(AdminRole.SUPER_ADMIN, AdminRole.ADMIN)
@Get('admin/consults/export')
async exportConsults(@CurrentAdmin() admin: AdminPayload, @Query() query: SearchConsultDto) {
return this.consultExportService.createExportJob(admin, query);
}
- 조회, 수정, 다운로드는 서로 다른 권한으로 분리해야 합니다.
- 특히 다운로드는 개인정보 유출 위험이 있으므로 더 엄격하게 제한하는 것이 좋습니다.
✅ 10. Service에서 데이터 범위 제한하기
- Guard는 “이 API를 호출할 수 있는지”를 검사합니다.
- 하지만 “어떤 데이터를 볼 수 있는지”는 Service에서 추가로 제한해야 합니다.
➕ 10-1. 상담 검색에서 데이터 범위 적용
async searchConsults(admin: AdminPayload, query: SearchConsultDto) {
const where: Prisma.ConsultWhereInput = {
...(query.status && { status: query.status }),
...(query.source && { source: query.source }),
};
if (admin.role === AdminRole.MANAGER) {
where.managerId = admin.id;
}
if (admin.role === AdminRole.MARKETER) {
where.source = {
in: ['NAVER', 'DANGGEUN', 'GOOGLE'],
};
}
return this.prisma.consult.findMany({
where,
orderBy: {
createdAt: 'desc',
},
});
}
- MANAGER는 본인 담당 데이터만 조회하게 제한했습니다.
- API 접근 권한과 데이터 범위 권한을 분리해서 생각해야 합니다.
✅ 11. 프론트엔드 권한 처리
- 프론트엔드에서도 권한에 따라 메뉴, 버튼, 컬럼을 숨길 수 있습니다.
- 하지만 프론트엔드 권한 처리는 보안이 아니라 UX 개선입니다.
➕ 11-1. 프론트엔드에서 할 수 있는 것
- 권한 없는 메뉴 숨기기
- 수정 버튼 숨기기
- 삭제 버튼 숨기기
- 엑셀 다운로드 버튼 숨기기
- 전화번호 일부 마스킹 표시
- 관리자 설정 메뉴 접근 제한 UI
➕ 11-2. 반드시 백엔드에서도 해야 하는 것
- API 호출 권한 검사
- 데이터 범위 제한
- 엑셀 다운로드 권한 검사
- 관리자 계정 생성 권한 검사
- 상품 삭제 권한 검사
- 설정 변경 권한 검사
프론트엔드:
버튼 숨김
백엔드:
권한 없는 요청은 403 Forbidden 반환
- 프론트엔드 버튼을 숨겼다고 끝내면 안 됩니다.
- 사용자는 개발자 도구나 API 클라이언트로 직접 요청을 보낼 수 있습니다.
✅ 12. 상태 코드 설계
- 권한 관련 API에서는 상태 코드를 정확히 구분하는 것이 좋습니다.
| 상태 코드 | 의미 | 예시 |
|---|
| 401 | 인증되지 않음 | 로그인 토큰 없음 |
| 403 | 권한 없음 | 로그인은 했지만 다운로드 권한 없음 |
| 404 | 리소스 없음 | 존재하지 않는 상담 데이터 |
| 409 | 충돌 | 이미 비활성화된 관리자 |
| 429 | 요청 과다 | 로그인 시도 너무 많음 |
➕ 12-1. 401과 403 차이
401 Unauthorized:
로그인이 필요함
토큰이 없음
토큰이 만료됨
403 Forbidden:
로그인은 했지만 이 기능을 사용할 권한이 없음
- 인증 실패와 권한 부족을 구분해야 디버깅이 쉬워집니다.
✅ 13. 관리자 계정 보안
- 관리자 계정은 고객 계정보다 더 높은 보안 수준이 필요합니다.
- 관리자 계정이 털리면 고객 데이터, 주문 데이터, 사이트 설정이 위험해질 수 있습니다.
➕ 13-1. 관리자 계정 보안 기준
- 비밀번호는 bcrypt/argon2로 해시 저장
- 로그인 실패 횟수 제한
- 오래된 계정 비활성화
- 퇴사자/외주 계정 즉시 비활성화
- 관리자 생성 권한 제한
- 관리자 권한 변경 이력 저장
- 가능하면 2FA 적용
- IP 제한 또는 관리자 URL 보호 검토
➕ 13-2. 로그인 실패 제한 예시
같은 계정으로 로그인 실패 5회
↓
10분간 로그인 제한
같은 IP에서 과도한 로그인 시도
↓
Rate Limit 적용
- Redis를 이용해 로그인 실패 횟수를 일정 시간 동안 관리할 수 있습니다.
✅ 14. 관리자 작업 이력
- 관리자 시스템에서는 누가 어떤 작업을 했는지 기록하는 것이 중요합니다.
- 특히 주문 상태 변경, 상담 메모 수정, 엑셀 다운로드, 상품 삭제, 배너 변경은 이력을 남기는 것이 좋습니다.
➕ 14-1. 이력이 필요한 작업
- 상담 상태 변경
- 상담 메모 수정
- 주문 상태 변경
- 상품 등록/수정/삭제
- 배너 등록/수정/삭제
- 관리자 계정 생성/권한 변경
- 엑셀 다운로드
- 시스템 설정 변경
- 사전예약 상태 변경
➕ 14-2. AdminActionLog 모델 예시
model AdminActionLog {
id Int @id @default(autoincrement())
adminId Int
action String
resource String
resourceId Int?
beforeData Json?
afterData Json?
ipAddress String?
userAgent String?
createdAt DateTime @default(now())
}
➕ 14-3. 기록 예시
{
"adminId": 3,
"action": "UPDATE_STATUS",
"resource": "CONSULT",
"resourceId": 123,
"beforeData": {
"status": "PENDING"
},
"afterData": {
"status": "DONE"
},
"ipAddress": "123.123.123.123"
}
- 이력은 장애 대응, 내부 감사, 고객 민원 대응, 운영 품질 개선에 도움이 됩니다.
- 단, 로그에 불필요한 개인정보를 과하게 저장하지 않도록 주의해야 합니다.
✅ 15. 개인정보 마스킹 권한
- 관리자 권한 설계에서 개인정보 마스킹은 매우 중요합니다.
- 모든 관리자가 전화번호 전체, 상담 메모, 첨부파일을 볼 필요는 없습니다.
➕ 15-1. 권한별 마스킹 예시
| 역할 | 이름 | 전화번호 | 상담 메모 | 엑셀 다운로드 |
|---|
| SUPER_ADMIN | 전체 | 전체 | 전체 | 가능 |
| ADMIN | 전체 | 전체 | 전체 | 가능 |
| MANAGER | 전체 | 전체 또는 일부 | 담당 건만 | 제한 |
| MARKETER | 마스킹 | 마스킹 | 불가 | 마스킹된 통계만 |
| VIEWER | 마스킹 | 마스킹 | 불가 | 불가 |
➕ 15-2. 마스킹 함수 예시
function maskPhone(phone: string) {
return phone.replace(/(\d{3})(\d{4})(\d{4})/, '$1****$3');
}
function maskName(name: string) {
if (name.length <= 1) {
return '*';
}
return name[0] + '*'.repeat(name.length - 1);
}
- 프론트엔드에서만 마스킹하면 API 응답에는 원본이 남습니다.
- 권한이 없는 사용자의 API 응답 자체에서 마스킹해서 내려주는 것이 더 안전합니다.
✅ 16. 관리자 메뉴와 API 권한 매핑
- 메뉴 권한과 API 권한을 따로 관리하면 불일치가 생길 수 있습니다.
- 가능하면 메뉴, 버튼, API 권한을 같은 권한 코드 기준으로 맞추는 것이 좋습니다.
➕ 16-1. 매핑 예시
| 메뉴/버튼 | 필요한 권한 |
|---|
| 상담 목록 메뉴 | consult:read |
| 상담 상태 변경 버튼 | consult:update |
| 상담 엑셀 다운로드 버튼 | consult:export |
| 상품 관리 메뉴 | product:read |
| 상품 등록 버튼 | product:create |
| 상품 삭제 버튼 | product:delete |
| 배너 관리 메뉴 | banner:read |
| 배너 수정 버튼 | banner:update |
| 관리자 관리 메뉴 | admin:read |
| 관리자 생성 버튼 | admin:create |
- 프론트엔드는 이 권한 코드를 보고 메뉴와 버튼을 보여줍니다.
- 백엔드는 같은 권한 코드를 기준으로 API 접근을 허용하거나 차단합니다.
✅ 17. 권한 설계에서 자주 하는 실수
➕ 17-1. 프론트엔드에서만 막기
버튼 숨김
↓
하지만 API 직접 호출 가능
↓
권한 우회 발생
➕ 17-2. 모든 관리자에게 전체 권한 부여
모든 관리자:
상담 전체 조회
엑셀 다운로드
상품 삭제
관리자 생성 가능
- 초기에는 편하지만 나중에 사고가 나기 쉽습니다.
- 최소한 조회, 수정, 삭제, 다운로드 권한은 구분하는 것이 좋습니다.
➕ 17-3. 삭제 권한을 쉽게 부여
- 삭제는 복구가 어렵거나 이력 관리가 복잡합니다.
- 가능하면 실제 삭제보다
deletedAt을 사용하는 Soft Delete를 고려할 수 있습니다.
실제 삭제:
데이터가 DB에서 사라짐
Soft Delete:
deletedAt만 기록하고 목록에서 숨김
➕ 17-4. 다운로드 이력 누락
- 엑셀 다운로드는 개인정보 유출 위험이 큽니다.
- 누가 언제 어떤 조건으로 다운로드했는지 기록해야 합니다.
✅ 18. 실무 체크리스트
➕ 18-1. 관리자 권한 체크리스트
- 관리자 역할이 정의되어 있는가?
- 역할별 사용 가능한 메뉴가 정리되어 있는가?
- 조회, 수정, 삭제, 다운로드 권한을 구분했는가?
- 관리자 계정 생성 권한을 제한했는가?
- 퇴사자/외주 계정을 비활성화하는 기준이 있는가?
- 비밀번호 해시와 로그인 실패 제한이 적용되어 있는가?
- 401과 403을 구분해서 반환하는가?
- 프론트엔드 버튼 숨김과 백엔드 권한 검사를 모두 적용했는가?
➕ 18-2. 데이터 범위 체크리스트
- MANAGER가 본인 담당 데이터만 볼 수 있는가?
- MARKETER가 개인정보 없이 유입 통계만 볼 수 있는가?
- VIEWER 권한은 수정/삭제/다운로드가 불가능한가?
- 엑셀 다운로드에서 권한별 마스킹이 적용되는가?
- API 응답에서 권한 없는 개인정보가 제거되는가?
- 관리자 직접 API 호출에도 데이터 범위 제한이 적용되는가?
➕ 18-3. 작업 이력 체크리스트
- 상담 상태 변경 이력이 남는가?
- 상품/배너 수정 이력이 남는가?
- 관리자 권한 변경 이력이 남는가?
- 엑셀 다운로드 이력이 남는가?
- before/after 데이터가 필요한 수준으로 저장되는가?
- 로그에 민감정보가 과도하게 저장되지 않는가?
- 문제 발생 시 누가 어떤 작업을 했는지 추적 가능한가?
✅ 19. AI를 활용해 관리자 권한을 설계할 때 질문법
- 관리자 권한 설계는 역할, 기능, 데이터 범위, 개인정보, 작업 이력을 함께 설명해야 정확한 답을 받을 수 있습니다.
- “관리자 권한 만들어줘”라고만 하면 너무 단순한 구조가 나올 가능성이 큽니다.
➕ 19-1. 좋은 질문 예시
NestJS + Prisma로 온라인 휴대폰 판매몰 관리자 권한 시스템을 설계하고 싶어.
상황:
1. 관리자 페이지에는 상담 신청 관리, 주문 관리, 상품 관리, 배너 관리, 엑셀 다운로드, 관리자 계정 관리가 있음
2. 역할은 SUPER_ADMIN, ADMIN, MANAGER, MARKETER, VIEWER 정도로 나누고 싶음
3. MANAGER는 본인 담당 상담만 수정 가능하게 하고 싶음
4. MARKETER는 광고 유입 통계는 볼 수 있지만 전화번호와 상담 메모는 마스킹하고 싶음
5. VIEWER는 조회만 가능하고 수정/삭제/다운로드는 불가능해야 함
6. 엑셀 다운로드는 이력을 남겨야 함
7. 프론트 메뉴 숨김과 백엔드 Guard를 함께 적용하고 싶음
요청:
- 역할별 권한표
- Prisma 모델 설계
- NestJS Guard 구조
- 데이터 범위 제한 방식
- 개인정보 마스킹 기준
- 관리자 작업 이력 테이블
- 401/403 상태 코드 기준
을 실무 기준으로 설명해줘.
➕ 19-2. AI 답변 검증 기준
- 인증과 인가를 구분하는가?
- 프론트엔드 버튼 숨김만으로는 부족하다고 설명하는가?
- 백엔드 Guard와 Service 데이터 범위 제한을 모두 고려하는가?
- 역할별 조회/수정/삭제/다운로드 권한을 나누는가?
- 개인정보 마스킹과 엑셀 다운로드 이력을 설명하는가?
- 관리자 작업 이력 테이블을 제안하는가?
- 401과 403을 정확히 구분하는가?
- 처음부터 과하게 복잡한 구조를 강요하지 않는가?
📌 요약
- 관리자 권한 설계는 관리자별로 어떤 기능과 데이터를 사용할 수 있는지 정하는 접근 제어 구조입니다.
- 인증은 “누구인지 확인”이고, 인가는 “무엇을 할 수 있는지 확인”입니다.
- 초기에는
SUPER_ADMIN, ADMIN, MANAGER, MARKETER, VIEWER 같은 역할 기반 권한으로 시작하는 것이 현실적입니다.
- 기능이 복잡해지면
consult:read, consult:update, consult:export 같은 Permission 기반 구조로 확장할 수 있습니다.
- 프론트엔드에서 메뉴와 버튼을 숨기는 것은 UX일 뿐이며, 실제 보안은 백엔드 Guard와 Service 레벨 권한 검사에서 처리해야 합니다.
- 기능 접근 권한뿐 아니라 본인 담당 데이터만 조회하는 데이터 범위 권한도 중요합니다.
- 엑셀 다운로드, 상담 상태 변경, 상품 삭제, 관리자 권한 변경 같은 작업은 반드시 이력을 남기는 것이 좋습니다.
- 개인정보는 권한에 따라 API 응답 단계에서 마스킹하거나 제외해야 하며, 다운로드 이력도 함께 관리해야 합니다.