TIL - 20260722

juni·2026년 7월 22일

TIL

목록 보기
411/468

0722 프론트엔드 실무 심화 (5/N): 권한 기반 UI, 라우팅 보호와 접근 제어 설계


✅ 1. 프론트엔드 권한 처리란 무엇인가?

  • 프론트엔드 권한 처리는 로그인한 사용자의 역할과 권한에 따라 화면, 메뉴, 버튼, 페이지 접근을 다르게 보여주는 작업입니다.
  • 관리자 페이지에서는 모든 사용자가 같은 기능을 보면 안 됩니다.
  • 상담 담당자, 상품 관리자, 마케터, 조회 전용 관리자, 최고 관리자가 할 수 있는 일이 다르기 때문입니다.
관리자 로그인
  ↓
내 정보/권한 조회
  ↓
메뉴 노출 제어
  ↓
페이지 접근 제어
  ↓
버튼/액션 노출 제어
  ↓
API 호출 시 백엔드 권한 재검사

➕ 1-1. 권한 처리가 중요한 이유

  • 권한 없는 관리자가 민감한 데이터를 보면 안 됩니다.
  • 실수로 주문, 상담, 상품, 배너를 수정하지 못하게 해야 합니다.
  • 엑셀 다운로드처럼 개인정보가 포함될 수 있는 기능은 더 강하게 제한해야 합니다.
  • 관리자별 업무 범위를 명확히 나눌 수 있습니다.
  • 운영 실수와 보안 사고를 줄일 수 있습니다.
프론트에서 버튼만 숨김
  ↓
사용자가 API URL을 직접 호출
  ↓
백엔드 권한 검사가 없으면 작업 성공

결론:
프론트 권한 처리는 UX
백엔드 권한 검사가 실제 보안
  • 프론트 권한 처리는 사용자가 헷갈리지 않게 하는 역할이고, 진짜 보안은 백엔드에서 막아야 합니다.

✅ 2. 인증과 인가의 차이

  • 인증(Authentication)은 사용자가 누구인지 확인하는 것입니다.
  • 인가(Authorization)는 그 사용자가 특정 작업을 할 수 있는지 판단하는 것입니다.
구분의미예시
인증로그인 여부 확인관리자 로그인
인가권한 확인엑셀 다운로드 가능 여부
역할사용자 그룹SUPER_ADMIN, ADMIN, MANAGER
권한구체적인 작업 가능 여부CONSULT_UPDATE, EXCEL_DOWNLOAD

➕ 2-1. 예시

인증:
이 사용자가 로그인한 관리자인가?

인가:
이 관리자가 상품을 수정할 수 있는가?
이 관리자가 엑셀을 다운로드할 수 있는가?
이 관리자가 다른 관리자 계정을 만들 수 있는가?
  • 로그인했다고 모든 관리자 기능을 쓸 수 있는 것은 아닙니다.
  • 관리자 페이지에서는 인증과 인가를 반드시 구분해야 합니다.

✅ 3. Role 기반 권한과 Permission 기반 권한

  • 권한 설계는 크게 Role 기반과 Permission 기반으로 나눌 수 있습니다.

➕ 3-1. Role 기반

SUPER_ADMIN
ADMIN
MANAGER
MARKETER
VIEWER
  • 역할별로 사용할 수 있는 기능을 정합니다.
  • 구조가 단순해서 작은 서비스에 적합합니다.

➕ 3-2. Permission 기반

CONSULT_READ
CONSULT_UPDATE
ORDER_READ
ORDER_UPDATE
PRODUCT_CREATE
PRODUCT_UPDATE
BANNER_UPDATE
EXCEL_DOWNLOAD
ADMIN_MANAGE
  • 작업 단위로 권한을 세밀하게 나눕니다.
  • 복잡하지만 역할이 많아질수록 유연합니다.

➕ 3-3. 현실적인 추천

초기:
Role 기반으로 시작

서비스가 커짐:
Role + Permission 조합

예시:
ADMIN 역할은 여러 permission 묶음
특정 관리자에게 일부 permission만 추가
  • 처음부터 너무 복잡한 권한 시스템을 만들 필요는 없습니다.
  • 하지만 엑셀 다운로드, 관리자 생성, 권한 변경 같은 위험 기능은 별도 권한으로 분리하는 것이 좋습니다.

✅ 4. 관리자 역할 예시

역할설명
SUPER_ADMIN전체 관리자, 계정/권한/설정 관리 가능
ADMIN일반 운영 관리자, 상담/주문/상품 관리 가능
MANAGER상담/주문 일부 처리 가능
MARKETER유입 통계, 광고 성과 조회 중심
VIEWER조회만 가능

➕ 4-1. 역할별 기능 예시

기능SUPER_ADMINADMINMANAGERMARKETERVIEWER
상담 목록 조회가능가능가능제한가능
상담 상태 변경가능가능담당 건만불가불가
주문 상태 변경가능가능제한불가불가
상품 수정가능가능불가불가불가
배너 수정가능가능불가불가불가
유입 통계 조회가능가능제한가능가능
엑셀 다운로드가능가능제한마스킹 통계만불가
관리자 계정 생성가능불가불가불가불가
  • 이런 표를 먼저 만들어두면 프론트와 백엔드 권한 기준을 맞추기 쉽습니다.

✅ 5. 프론트엔드에서 권한 정보를 어디서 가져올까?

  • 권한 정보는 보통 로그인 후 me API에서 가져옵니다.
  • 토큰 안에 role이 들어있더라도, 화면에서는 서버에서 최신 사용자 정보를 조회하는 방식이 안전합니다.

➕ 5-1. me API 응답 예시

{
  "id": 3,
  "name": "신동준",
  "email": "admin@example.com",
  "role": "ADMIN",
  "permissions": [
    "CONSULT_READ",
    "CONSULT_UPDATE",
    "PRODUCT_UPDATE",
    "EXCEL_DOWNLOAD"
  ]
}

➕ 5-2. TanStack Query로 관리자 정보 조회

const meQuery = useQuery({
  queryKey: ['auth', 'me'],
  queryFn: () => authApi.getMe(),
  staleTime: 1000 * 60 * 5,
});
  • 로그인한 관리자 정보는 여러 화면에서 필요합니다.
  • 전역 상태로 복사하기보다 useMe() 같은 hook으로 감싸서 쓰면 관리가 쉽습니다.

✅ 6. useMe Hook

  • 관리자 정보 조회를 화면마다 직접 작성하면 반복됩니다.
  • useMe hook으로 감싸두면 권한 체크와 로딩 처리를 통일할 수 있습니다.
export function useMe() {
  return useQuery({
    queryKey: ['auth', 'me'],
    queryFn: () => authApi.getMe(),
    staleTime: 1000 * 60 * 5,
    retry: false,
  });
}

➕ 6-1. 사용 예시

function AdminHeader() {
  const { data: me, isLoading } = useMe();

  if (isLoading) {
    return <span>관리자 정보를 불러오는 중...</span>;
  }

  return <span>{me?.name}님</span>;
}
  • useMe는 관리자 메뉴, 권한 버튼, 페이지 보호에서 모두 재사용됩니다.
  • 로그인 만료 처리는 공통 API client interceptor와 함께 처리하면 좋습니다.

✅ 7. 권한 체크 유틸 함수

  • 권한 체크 로직이 컴포넌트마다 흩어지면 유지보수가 어렵습니다.
  • 공통 유틸 함수로 관리하는 것이 좋습니다.

➕ 7-1. Permission 타입

export type Permission =
  | 'CONSULT_READ'
  | 'CONSULT_UPDATE'
  | 'ORDER_READ'
  | 'ORDER_UPDATE'
  | 'PRODUCT_UPDATE'
  | 'BANNER_UPDATE'
  | 'EXCEL_DOWNLOAD'
  | 'ADMIN_MANAGE';

➕ 7-2. hasPermission 함수

export function hasPermission(
  userPermissions: Permission[] | undefined,
  requiredPermission: Permission,
) {
  if (!userPermissions) {
    return false;
  }

  return userPermissions.includes(requiredPermission);
}

➕ 7-3. 여러 권한 체크

export function hasAnyPermission(
  userPermissions: Permission[] | undefined,
  requiredPermissions: Permission[],
) {
  if (!userPermissions) {
    return false;
  }

  return requiredPermissions.some((permission) =>
    userPermissions.includes(permission),
  );
}
  • 권한 판단 기준은 한 곳에 모아야 합니다.
  • 그래야 권한명이 바뀌거나 정책이 바뀌어도 수정 범위가 줄어듭니다.

✅ 8. Role 체크 유틸 함수

  • Permission까지 세밀하게 나누지 않은 초기 서비스라면 role 기준으로도 충분할 수 있습니다.
export type AdminRole =
  | 'SUPER_ADMIN'
  | 'ADMIN'
  | 'MANAGER'
  | 'MARKETER'
  | 'VIEWER';
export function hasRole(
  userRole: AdminRole | undefined,
  allowedRoles: AdminRole[],
) {
  if (!userRole) {
    return false;
  }

  return allowedRoles.includes(userRole);
}

➕ 8-1. 사용 예시

const canManageAdmins = hasRole(me?.role, ['SUPER_ADMIN']);
  • Role 체크는 단순합니다.
  • 하지만 “ADMIN은 상품 수정 가능하지만 엑셀 다운로드는 불가” 같은 예외가 많아지면 Permission 기반이 더 적합합니다.

✅ 9. 권한 기반 메뉴 노출

  • 관리자 사이드바 메뉴는 권한에 따라 다르게 보여야 합니다.
  • 접근할 수 없는 메뉴를 계속 보여주면 사용자가 혼란스러워집니다.

➕ 9-1. 메뉴 정의 예시

const adminMenus = [
  {
    label: '상담 관리',
    href: '/admin/consults',
    requiredPermission: 'CONSULT_READ',
  },
  {
    label: '주문 관리',
    href: '/admin/orders',
    requiredPermission: 'ORDER_READ',
  },
  {
    label: '상품 관리',
    href: '/admin/products',
    requiredPermission: 'PRODUCT_UPDATE',
  },
  {
    label: '배너 관리',
    href: '/admin/banners',
    requiredPermission: 'BANNER_UPDATE',
  },
  {
    label: '관리자 관리',
    href: '/admin/admins',
    requiredPermission: 'ADMIN_MANAGE',
  },
] as const;

➕ 9-2. 메뉴 필터링

const visibleMenus = adminMenus.filter((menu) =>
  hasPermission(me?.permissions, menu.requiredPermission),
);
  • 메뉴 정의와 권한 조건을 한 곳에서 관리하면 편합니다.
  • 단, 메뉴를 숨겼다고 백엔드 API 권한 검사를 생략하면 안 됩니다.

✅ 10. 권한 기반 버튼 노출

  • 관리자 테이블의 액션 버튼도 권한에 따라 달라져야 합니다.

➕ 10-1. 상담 테이블 액션 예시

const canUpdateConsult = hasPermission(
  me?.permissions,
  'CONSULT_UPDATE',
);

return (
  <div>
    <button type="button" onClick={openDetail}>
      상세
    </button>

    {canUpdateConsult && (
      <button type="button" onClick={openStatusModal}>
        상태 변경
      </button>
    )}
  </div>
);

➕ 10-2. 숨김과 비활성화 기준

방식적합한 상황
숨김사용자가 알 필요 없는 기능
비활성화기능은 보이지만 현재 조건상 불가
권한 없음 안내권한 요청이 필요한 기능
권한 자체가 없음:
버튼 숨김

권한은 있지만 현재 상태에서 불가:
버튼 disabled + 이유 안내

예:
DONE 상태라 더 이상 변경 불가
  • 권한 없음과 상태상 불가능은 구분해서 보여주는 것이 좋습니다.

✅ 11. 페이지 접근 보호

  • 메뉴만 숨기는 것으로는 부족합니다.
  • 사용자가 URL을 직접 입력해 접근할 수 있기 때문에 페이지 단위 보호가 필요합니다.

➕ 11-1. ProtectedRoute 개념

페이지 진입
  ↓
로그인 여부 확인
  ↓
권한 확인
  ↓
가능하면 페이지 렌더링
  ↓
불가능하면 로그인/권한 없음 페이지로 이동

➕ 11-2. React Router 예시

type ProtectedRouteProps = {
  requiredPermission?: Permission;
  children: React.ReactNode;
};

function ProtectedRoute({
  requiredPermission,
  children,
}: ProtectedRouteProps) {
  const { data: me, isLoading, isError } = useMe();

  if (isLoading) {
    return <PageLoading />;
  }

  if (isError || !me) {
    return <Navigate to="/admin/login" replace />;
  }

  if (
    requiredPermission &&
    !hasPermission(me.permissions, requiredPermission)
  ) {
    return <ForbiddenPage />;
  }

  return <>{children}</>;
}

➕ 11-3. 사용 예시

<ProtectedRoute requiredPermission="PRODUCT_UPDATE">
  <AdminProductPage />
</ProtectedRoute>
  • 페이지 접근 보호는 사용자 경험과 보안 보조 역할입니다.
  • 실제 API 권한은 백엔드에서 반드시 다시 확인해야 합니다.

✅ 12. Next.js에서 라우팅 보호

  • Next.js를 사용한다면 middleware, server component, client guard 등을 조합할 수 있습니다.
  • 구조에 따라 달라지지만 기본 원칙은 같습니다.

➕ 12-1. 보호해야 하는 경로

 /admin
 /admin/consults
 /admin/orders
 /admin/products
 /admin/banners
 /admin/settings

➕ 12-2. 클라이언트 Guard 예시

function AdminPageGuard({
  requiredPermission,
  children,
}: {
  requiredPermission?: Permission;
  children: React.ReactNode;
}) {
  const { data: me, isLoading, isError } = useMe();

  if (isLoading) {
    return <PageLoading />;
  }

  if (isError || !me) {
    redirect('/admin/login');
  }

  if (
    requiredPermission &&
    !hasPermission(me.permissions, requiredPermission)
  ) {
    return <ForbiddenPage />;
  }

  return <>{children}</>;
}
  • Next.js에서는 서버/클라이언트 렌더링 방식에 따라 구현이 달라질 수 있습니다.
  • 중요한 것은 “로그인 전 화면 깜빡임”과 “권한 없는 화면 노출”을 최소화하는 것입니다.

✅ 13. 로그인 만료 처리

  • 관리자 페이지에서 로그인 만료는 흔한 상황입니다.
  • 토큰이 만료되면 사용자를 로그인 페이지로 보내거나, 재로그인 모달을 보여줘야 합니다.

➕ 13-1. API Client Interceptor 흐름

API 요청
  ↓
401 응답
  ↓
토큰 만료 판단
  ↓
로그아웃 처리
  ↓
로그인 페이지 이동
  ↓
안내 메시지 표시

➕ 13-2. 에러 메시지

로그인 시간이 만료되었습니다.
다시 로그인해 주세요.

➕ 13-3. 주의할 점

401을 무조건 서버 장애로 보여주지 않기
무한 refresh token 재시도 방지
로그아웃 후 민감한 캐시 데이터 제거
관리자 정보 query cache 제거
  • 로그인 만료 처리는 화면마다 따로 하지 말고 공통 API client에서 처리하는 것이 좋습니다.

✅ 14. 권한 없음 페이지

  • 권한이 없는 페이지에 접근했을 때는 명확한 안내가 필요합니다.
  • 빈 화면이나 404로 처리하면 사용자가 혼란스러워집니다.

➕ 14-1. 권한 없음 메시지

이 페이지에 접근할 권한이 없습니다.
필요한 경우 최고 관리자에게 권한을 요청해 주세요.

➕ 14-2. 제공하면 좋은 버튼

이전 페이지로 돌아가기
대시보드로 이동
로그아웃

➕ 14-3. 주의할 점

  • “이 기능은 SUPER_ADMIN만 가능합니다”처럼 내부 권한 구조를 너무 자세히 노출할 필요는 없습니다.
  • 관리자 내부 서비스라면 어느 정도 안내해도 되지만, 외부 사용자에게는 최소 정보만 보여주는 것이 좋습니다.

✅ 15. 권한과 데이터 범위

  • 권한은 “기능 사용 가능 여부”만이 아닙니다.
  • 어떤 데이터를 볼 수 있는지도 권한의 일부입니다.

➕ 15-1. 예시

SUPER_ADMIN:
전체 상담 조회 가능

ADMIN:
전체 상담 조회 가능

MANAGER:
본인 담당 상담만 조회 가능

MARKETER:
개인정보 마스킹된 유입 통계만 조회 가능

VIEWER:
조회만 가능, 다운로드 불가

➕ 15-2. 프론트에서 고려할 것

담당자 필터 노출 여부
전체 데이터 보기 버튼 노출 여부
전화번호 마스킹 표시
엑셀 다운로드 버튼 제한
통계 상세 drill-down 제한
  • 데이터 범위 제한은 반드시 백엔드 쿼리에서 처리해야 합니다.
  • 프론트에서만 필터링하면 API 응답에는 이미 데이터가 내려온 것이기 때문에 보안상 위험합니다.

✅ 16. 개인정보 마스킹 UI

  • 관리자 권한에 따라 개인정보 표시 수준이 달라질 수 있습니다.
  • 전화번호, 이름, 이메일, 주소, 상담 메모는 특히 조심해야 합니다.

➕ 16-1. 권한별 표시 예시

권한전화번호 표시
SUPER_ADMIN01012345678
ADMIN01012345678
MANAGER010****5678 또는 담당 건만 전체
MARKETER마스킹
VIEWER마스킹

➕ 16-2. 프론트 표시 예시

<span>{consult.phone}</span>
  • 여기서 중요한 점은 프론트가 직접 마스킹하는 것보다, 백엔드가 권한에 맞게 마스킹된 값을 내려주는 것이 더 안전하다는 점입니다.
  • 프론트에는 이미 전체 전화번호가 내려왔는데 화면에서만 가리는 방식은 보안상 부족합니다.

✅ 17. 엑셀 다운로드 권한

  • 엑셀 다운로드는 개인정보 대량 유출 위험이 있기 때문에 특별히 강하게 봐야 합니다.
  • 목록 조회 권한과 엑셀 다운로드 권한은 분리하는 것이 좋습니다.

➕ 17-1. 권한 분리 예시

CONSULT_READ:
상담 목록 조회 가능

CONSULT_EXPORT:
상담 목록 엑셀 다운로드 가능

CONSULT_EXPORT_UNMASKED:
마스킹 없는 엑셀 다운로드 가능

➕ 17-2. 프론트 UI 기준

권한 없음:
엑셀 다운로드 버튼 숨김

권한 있음:
현재 필터 조건 기준 다운로드

민감정보 포함:
Confirm으로 안내

다운로드 요청 후:
ExportJob 생성 안내

➕ 17-3. Confirm 메시지 예시

현재 검색 조건에 해당하는 상담 내역을 엑셀로 생성하시겠습니까?
파일에는 개인정보가 포함될 수 있으므로 다운로드 및 공유에 주의해 주세요.
  • 엑셀 다운로드는 관리자 작업 이력에도 남기는 것이 좋습니다.

✅ 18. 권한 기반 API 에러 처리

  • 프론트에서 권한 버튼을 숨겨도 API에서 403이 올 수 있습니다.
  • 권한 변경, 로그인 만료, 다른 기기 로그인, 백엔드 정책 변경 등으로 화면 상태와 서버 권한이 달라질 수 있기 때문입니다.

➕ 18-1. 403 처리 기준

목록 조회 403:
권한 없음 페이지 또는 안내

버튼 액션 403:
토스트 또는 모달로 권한 없음 안내

엑셀 다운로드 403:
다운로드 권한이 없다는 안내

관리자 관리 403:
대시보드로 이동 유도

➕ 18-2. 메시지 예시

이 작업을 수행할 권한이 없습니다.
필요한 경우 최고 관리자에게 권한을 요청해 주세요.
  • 403을 일반 서버 오류로 처리하면 안 됩니다.
  • 권한 문제는 권한 문제로 정확히 알려주는 것이 좋습니다.

✅ 19. 권한 변경 후 캐시 갱신

  • 관리자 권한이 변경되면 프론트의 me 정보도 갱신되어야 합니다.
  • 그렇지 않으면 화면에는 버튼이 남아 있는데 API는 403을 반환하는 상황이 생깁니다.

➕ 19-1. 권한 변경 후 처리

queryClient.invalidateQueries({
  queryKey: ['auth', 'me'],
});

➕ 19-2. 관리자가 다른 관리자의 권한을 수정한 경우

queryClient.invalidateQueries({
  queryKey: ['admin', 'admins'],
});
  • 내 권한이 바뀌었는지 확인하려면 me query를 갱신해야 합니다.
  • 관리자 목록을 수정했다면 관리자 목록 query도 갱신해야 합니다.

✅ 20. 권한 기준 문서화

  • 권한은 코드로만 두면 나중에 헷갈립니다.
  • 역할별 권한 표를 문서로 남겨야 합니다.

➕ 20-1. 문서에 넣을 것

역할 목록
권한 목록
역할별 가능 기능
데이터 범위
개인정보 마스킹 기준
엑셀 다운로드 가능 여부
관리자 생성/수정 가능 여부
백엔드 Guard 기준
프론트 메뉴/버튼 노출 기준

➕ 20-2. 문서 예시

## 관리자 권한 정책

### 역할
- SUPER_ADMIN: 전체 관리
- ADMIN: 일반 운영 관리
- MANAGER: 상담/주문 일부 처리
- MARKETER: 유입 통계 조회
- VIEWER: 조회 전용

### 주요 권한
| 권한 | 설명 |
|---|---|
| CONSULT_READ | 상담 목록 조회 |
| CONSULT_UPDATE | 상담 상태 변경 |
| CONSULT_EXPORT | 상담 엑셀 다운로드 |
| PRODUCT_UPDATE | 상품 수정 |
| ADMIN_MANAGE | 관리자 계정 관리 |

### 개인정보 표시
- SUPER_ADMIN/ADMIN: 담당 업무 범위 내 전체 표시
- MANAGER: 담당 건만 전체 표시
- MARKETER/VIEWER: 마스킹 표시

### 주의사항
- 프론트 메뉴/버튼 숨김은 UX 목적
- 실제 권한 검사는 백엔드 Guard에서 처리
- 엑셀 다운로드는 작업 이력 저장 필수
  • 권한 문서는 운영자와 대표에게 설명하기에도 좋습니다.
  • 나중에 관리자 역할이 늘어날 때 기준이 됩니다.

✅ 21. 프론트 권한 처리에서 자주 하는 실수

➕ 21-1. 프론트만 믿는 실수

버튼 숨김
  ↓
API 권한 검사 없음
  ↓
직접 호출하면 작업 가능
  • 이건 보안 사고입니다.
  • 백엔드 Guard나 middleware에서 반드시 막아야 합니다.

➕ 21-2. 권한 조건이 여러 곳에 흩어짐

if (me.role === 'ADMIN' || me.role === 'SUPER_ADMIN') {
  // 버튼 표시
}
  • 이런 코드가 여러 화면에 반복되면 정책 변경 시 모두 수정해야 합니다.
  • hasPermission, canUpdateConsult, canDownloadExcel 같은 함수로 모으는 것이 좋습니다.

➕ 21-3. 권한 없음과 데이터 없음을 혼동

권한 없음:
조회할 수 없는 데이터

데이터 없음:
조회 권한은 있지만 조건에 맞는 데이터 없음
  • 둘은 메시지가 달라야 합니다.
  • 권한 없음은 403, 데이터 없음은 Empty 상태입니다.

➕ 21-4. 개인정보를 프론트에서만 마스킹

백엔드:
전체 전화번호 내려줌

프론트:
화면에서만 010****5678로 표시

문제:
브라우저 devtools나 네트워크 탭에서 전체 전화번호 확인 가능
  • 권한별 개인정보 마스킹은 백엔드 응답 단계에서 처리하는 것이 안전합니다.

✅ 22. 실무 체크리스트

➕ 22-1. 인증 체크리스트

  1. 관리자 로그인 여부를 확인하는가?
  2. 로그인 만료 시 로그인 페이지로 이동하는가?
  3. 401 응답을 공통 처리하는가?
  4. 로그아웃 시 민감한 query cache를 제거하는가?
  5. me API로 최신 관리자 정보를 가져오는가?
  6. 관리자 정보 로딩 중 화면 깜빡임을 최소화했는가?
  7. 토큰을 로그에 남기지 않는가?
  8. 로그인 만료 메시지가 사용자에게 명확한가?

➕ 22-2. 인가 체크리스트

  1. 페이지별 requiredPermission이 정의되어 있는가?
  2. 메뉴 노출이 권한에 따라 달라지는가?
  3. 버튼 액션이 권한에 따라 제한되는가?
  4. 권한 없음 페이지가 있는가?
  5. API 403 응답을 권한 문제로 처리하는가?
  6. 권한 조건이 공통 함수로 관리되는가?
  7. 권한 변경 후 me query를 갱신하는가?
  8. 백엔드에서도 같은 권한을 검사하는가?

➕ 22-3. 개인정보/엑셀 체크리스트

  1. 개인정보 표시 기준이 권한별로 정의되어 있는가?
  2. 백엔드 응답에서 마스킹이 적용되는가?
  3. 엑셀 다운로드 권한이 목록 조회 권한과 분리되어 있는가?
  4. 엑셀 다운로드 전 Confirm이 있는가?
  5. 다운로드 파일에 개인정보가 포함될 수 있음을 안내하는가?
  6. 엑셀 다운로드 이력이 저장되는가?
  7. 권한 없는 사용자가 다운로드 API를 직접 호출해도 막히는가?
  8. 마케터/조회 전용 계정은 민감정보를 볼 수 없게 되어 있는가?

➕ 22-4. 문서화 체크리스트

  1. 역할별 권한 표가 있는가?
  2. Permission 목록이 문서화되어 있는가?
  3. 메뉴 노출 기준이 정리되어 있는가?
  4. 버튼 액션 기준이 정리되어 있는가?
  5. 개인정보 마스킹 기준이 정리되어 있는가?
  6. 엑셀 다운로드 기준이 정리되어 있는가?
  7. 백엔드 Guard와 프론트 권한 조건이 같은 정책을 바라보는가?
  8. 권한 정책 변경 시 문서와 코드가 함께 수정되는가?

✅ 23. AI를 활용해 권한 기반 UI를 설계할 때 질문법

  • AI에게 권한 기반 UI를 설계시킬 때는 역할, 권한, 메뉴, 버튼, 데이터 범위, 개인정보 표시 기준, 백엔드 권한 검사 여부를 함께 알려줘야 합니다.
  • “권한 처리 어떻게 해?”라고만 하면 너무 일반적인 답변이 나옵니다.

➕ 23-1. 좋은 질문 예시

React + TanStack Query 기반 관리자 페이지에서 권한 기반 UI와 라우팅 보호를 설계하고 싶어.

상황:
1. 관리자 역할은 SUPER_ADMIN, ADMIN, MANAGER, MARKETER, VIEWER가 있음
2. 권한은 CONSULT_READ, CONSULT_UPDATE, CONSULT_EXPORT, PRODUCT_UPDATE, BANNER_UPDATE, ADMIN_MANAGE가 있음
3. 로그인 후 me API에서 role과 permissions를 가져옴
4. 상담 관리, 주문 관리, 상품 관리, 배너 관리, 관리자 관리 메뉴가 있음
5. VIEWER는 조회만 가능하고 상태 변경/엑셀 다운로드는 불가
6. MARKETER는 유입 통계는 볼 수 있지만 개인정보는 마스킹되어야 함
7. 엑셀 다운로드는 별도 권한이 필요하고 Confirm을 띄워야 함
8. 권한 없는 페이지 접근 시 ForbiddenPage를 보여주고 싶음
9. 실제 보안은 백엔드 Guard에서 다시 검사함

요청:
- me API 기반 권한 상태 관리
- useMe hook 구조
- hasPermission/hasRole 유틸
- 메뉴 노출 기준
- 버튼 노출/disabled 기준
- ProtectedRoute 구조
- 401/403 처리 기준
- 개인정보 마스킹 UI 기준
- 엑셀 다운로드 권한 UX
- 권한 정책 문서 템플릿
을 실무 기준으로 정리해줘.

➕ 23-2. AI 답변 검증 기준

  1. 프론트 버튼 숨김을 실제 보안으로 착각하지 않는가?
  2. 백엔드 권한 검사를 반드시 언급하는가?
  3. 로그인 여부와 권한 여부를 구분하는가?
  4. Role과 Permission의 차이를 설명하는가?
  5. 메뉴, 페이지, 버튼, 데이터 범위를 나눠서 설계하는가?
  6. 개인정보 마스킹을 백엔드 응답 기준으로 처리하라고 하는가?
  7. 401과 403 UI 처리를 구분하는가?
  8. 현재 서비스 규모에 맞게 과하게 복잡하지 않은가?

📌 요약

  • 프론트엔드 권한 처리는 로그인한 관리자 역할과 권한에 따라 메뉴, 페이지, 버튼, 데이터 표시를 다르게 보여주는 작업입니다.
  • 인증은 사용자가 누구인지 확인하는 것이고, 인가는 그 사용자가 특정 기능이나 데이터에 접근할 수 있는지 판단하는 것입니다.
  • 작은 서비스는 Role 기반으로 시작해도 되지만, 엑셀 다운로드, 관리자 계정 관리, 개인정보 표시처럼 위험한 기능은 Permission으로 분리하는 것이 좋습니다.
  • 로그인한 관리자 정보는 me API로 조회하고, useMe hook으로 감싸서 메뉴, 버튼, 페이지 보호에서 재사용하면 좋습니다.
  • 메뉴와 버튼은 권한에 따라 숨기거나 비활성화할 수 있지만, 실제 보안은 백엔드 Guard/API 권한 검사에서 반드시 처리해야 합니다.
  • 권한 없는 페이지 접근은 ForbiddenPage로 안내하고, 로그인 만료인 401과 권한 부족인 403은 UI 처리를 구분해야 합니다.
  • 데이터 범위도 권한의 일부입니다. MANAGER는 담당 건만 보고, MARKETER는 마스킹된 통계만 보는 식으로 설계할 수 있습니다.
  • 개인정보 마스킹은 프론트에서만 처리하면 네트워크 응답에 원본이 남기 때문에, 백엔드가 권한에 맞게 마스킹된 값을 내려주는 것이 안전합니다.
  • 엑셀 다운로드는 목록 조회보다 더 위험한 기능이므로 별도 권한, Confirm, 작업 이력 저장이 필요합니다.
  • 권한 정책은 코드뿐 아니라 역할별 권한 표, 개인정보 표시 기준, 엑셀 다운로드 기준까지 문서화해야 운영 중 혼란을 줄일 수 있습니다.

0개의 댓글