Files
sam-react-prod/claudedocs/settings/[ANALYSIS-2026-01-07] permission-system-status.md
유병철 b59150551e chore(WEB): PermissionManagement 오류 수정 및 claudedocs 폴더 정리
- PermissionManagement externalSelection 콜백 함수 오류 수정
  - setSelectedItems → onToggleSelection, onToggleSelectAll, getItemId 변경
- claudedocs 문서 폴더별 정리 (26개 파일)
  - dashboard/, guides/, settings/, construction/, sales/ 등

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-17 13:11:35 +09:00

8.5 KiB

권한 관리 시스템 현황 분석

작성일: 2026-01-07 최종 수정일: 2026-01-12 목적: SAM 프로젝트 권한 시스템 현황 파악 및 향후 구현 계획 정리


1. 현재 상태 요약

구분 상태 설명
권한 설정 UI 완성 /settings/permissions/[id]에서 역할별 권한 설정 가능
백엔드 권한 API 완성 권한 매트릭스 조회/설정 API 구현됨
백엔드 API 권한 체크 ⚠️ 구조만 있음 미들웨어 존재하나 라우트에 미적용
프론트 권한 체크 미구현 권한 매트릭스 조회 및 UI 제어 로직 없음

2. 권한 타입 (5가지)

권한 영문 적용 대상
조회 view 페이지 접근
생성 create 등록/추가 버튼
수정 update 수정 버튼
삭제 delete 삭제 버튼
승인 approve 승인/반려 버튼

⚠️ 참고: export, manage 권한은 백엔드에 미구현 상태


3. 백엔드 API 구조

3.1 로그인 API

엔드포인트: POST /api/v1/login

응답 구조:

{
  "access_token": "...",
  "refresh_token": "...",
  "user": { "id": 1, "name": "..." },
  "menus": [...],
  "roles": [...]
}

⚠️ 주의: 로그인 응답에 권한 매트릭스(permissions)는 포함되지 않음

3.2 권한 매트릭스 조회 API

사용자별 권한 조회 (프론트엔드에서 사용):

GET /api/v1/permissions/users/{userId}/menu-matrix

실제 응답 구조:

{
  "success": true,
  "message": "유저 메뉴 권한 매트릭스 조회 성공",
  "data": {
    "actions": ["view", "create", "update", "delete", "approve"],
    "tree": [
      {
        "menu_id": 1,
        "parent_id": null,
        "name": "대시보드",
        "url": "/dashboard",
        "type": "system",
        "children": [
          {
            "menu_id": 2,
            "parent_id": 1,
            "name": "CEO 대시보드",
            "url": "/dashboard/ceo",
            "children": [],
            "actions": { ... }
          }
        ],
        "actions": {
          "view": {
            "permission_id": 123,
            "permission_code": "menu:1.view",
            "guard_name": "api",
            "state": "allow",
            "is_allowed": 1
          },
          "create": {
            "permission_id": 124,
            "permission_code": "menu:1.create",
            "guard_name": "api",
            "state": "deny",
            "is_allowed": 0
          },
          "update": null,
          "delete": null,
          "approve": null
        }
      }
    ]
  }
}

권한 상태 값:

state is_allowed 의미
allow 1 권한 허용됨
deny 0 권한 명시적 거부
none 0 권한 미설정 (기본 거부)

actions가 null인 경우: 해당 메뉴에 해당 권한이 정의되지 않음

3.3 권한 매트릭스 API 목록

엔드포인트 메서드 설명
/api/v1/permissions/users/{user_id}/menu-matrix GET 사용자별 권한 매트릭스
/api/v1/permissions/roles/{role_id}/menu-matrix GET 역할별 권한 매트릭스
/api/v1/permissions/departments/{dept_id}/menu-matrix GET 부서별 권한 매트릭스

3.4 역할 권한 관리 API

엔드포인트 메서드 설명
/api/v1/role-permissions/menus GET 권한 설정용 메뉴 트리
/api/v1/roles/{id}/permissions GET 역할 권한 목록
/api/v1/roles/{id}/permissions POST 역할 권한 부여
/api/v1/roles/{id}/permissions DELETE 역할 권한 회수
/api/v1/roles/{id}/permissions/sync PUT 역할 권한 동기화
/api/v1/roles/{id}/permissions/matrix GET 역할 권한 매트릭스 (설정 UI용)
/api/v1/roles/{id}/permissions/toggle POST 개별 권한 토글
/api/v1/roles/{id}/permissions/allow-all POST 전체 허용
/api/v1/roles/{id}/permissions/deny-all POST 전체 거부
/api/v1/roles/{id}/permissions/reset POST 기본값 초기화 (view만 허용)

4. 백엔드 권한 체크 미들웨어

4.1 CheckPermission.php

// 권한 체크 로직
if (! AccessService::allows($user, $perm, $tenantId, 'api')) {
    return response()->json(['message' => '권한이 없습니다.'], 403);
}

// 단, perm 미지정 라우트는 통과 (현재 정책)
if (! $perm && ! $permsAny) {
    return $next($request);  // ← 현재 모든 API가 여기로 통과
}

4.2 PermMapper.php

HTTP 메서드에 따라 액션 자동 매핑:

HTTP 메서드 권한 액션
GET, HEAD view
POST create
PUT, PATCH update
DELETE delete

권한 형식: menu:{menuId}.{action} (예: menu:1.view)

4.3 현재 상태

  • 미들웨어 구조는 갖춰져 있음
  • 라우트에 menu_id 설정이 안 되어 있어 실제 권한 체크 미동작
  • 모든 API가 권한 체크 없이 통과

5. 프론트엔드 현재 상태

5.1 구현된 것

  • 로그인 시 menus, roles 데이터 저장 (localStorage)
  • 사이드바 메뉴 표시 (백엔드에서 필터링된 메뉴)
  • 메뉴 폴링 (30초 주기)
  • 역할별 권한 설정 UI (/settings/permissions/[id])

5.2 미구현 사항

  • 권한 매트릭스 API 호출
  • 권한 데이터 저장 (permissionStore)
  • usePermission
  • 페이지/버튼별 권한 체크
  • 환경 변수 플래그

6. 향후 구현 계획

6.1 프론트엔드 (1단계 - UI 제어)

로그인 성공
    ↓
/api/v1/permissions/users/{userId}/menu-matrix 호출
    ↓
권한 매트릭스 저장 (Zustand permissionStore)
    ↓
usePermission 훅으로 권한 체크
    ↓
버튼/기능 숨김/비활성화

usePermission 훅 예시:

// 사용법 (메뉴명 또는 URL로 조회)
const { canView, canCreate, canUpdate, canDelete, canApprove } = usePermission('/sales/orders');

// 적용
{canCreate && <Button>등록</Button>}
{canDelete && <Button>삭제</Button>}
{canApprove && <Button>승인</Button>}

환경 변수 플래그:

NEXT_PUBLIC_ENABLE_AUTHORIZATION=false  # 개발 중에는 비활성화

6.2 백엔드 (2단계 - API 보안)

라우트에 menu_id 설정하여 API 레벨 권한 체크 활성화:

// 예시: routes/api.php
Route::get('/orders', [OrderController::class, 'index'])
    ->defaults('menu_id', 5);  // 판매관리 메뉴 ID

Route::post('/orders', [OrderController::class, 'store'])
    ->defaults('menu_id', 5);  // POST → create 권한 자동 체크

7. 보안 고려사항

7.1 현재 취약점

  • 프론트에서만 UI 숨기면 개발자 도구로 우회 가능
  • 직접 API 호출 시 권한 없이도 작업 가능

7.2 권장 구조 (이중 보안)

프론트엔드: UI 컨트롤 (UX 향상)
    ↓
백엔드: API 권한 체크 (실제 보안)
    ↓
권한 없으면 403 반환

8. 관련 파일 경로

프론트엔드 (sam-react-prod)

파일 설명
src/app/[locale]/(protected)/settings/permissions/ 권한 설정 페이지
src/components/settings/PermissionManagement/ 권한 관리 컴포넌트
src/layouts/AuthenticatedLayout.tsx 메뉴 표시 레이아웃
src/middleware.ts 인증 체크 (권한 체크 없음)
src/store/menuStore.ts 메뉴 상태 관리

백엔드 (sam-api)

파일 설명
app/Http/Controllers/Api/V1/PermissionController.php 권한 매트릭스 API
app/Http/Controllers/Api/V1/RolePermissionController.php 역할 권한 API
app/Http/Middleware/CheckPermission.php 권한 체크 미들웨어
app/Http/Middleware/PermMapper.php HTTP → 액션 매핑
app/Services/PermissionService.php 권한 매트릭스 서비스
app/Services/Authz/AccessService.php 권한 판정 서비스
app/Services/Authz/RolePermissionService.php 역할 권한 서비스

9. 결론

현재: 권한 설정은 가능하지만, 프론트/백엔드 모두 권한 체크 미적용

1단계 (프론트):

  • 로그인 후 권한 매트릭스 API 호출
  • usePermission 훅으로 UI 제어
  • 환경 변수로 개발 중 비활성화

2단계 (백엔드):

  • 라우트에 menu_id 설정
  • API 레벨 권한 체크 활성화

이 문서는 권한 시스템 구현 시 참고용으로 작성되었습니다.