인증과 인가

한 줄 정의

인증은 사용자가 누구인지 확인하는 과정이고, 인가는 확인된 사용자가 특정 리소스나 기능에 접근할 수 있는지 판단하는 과정이다.

실무에서 왜 문제 되는가

  • 인증과 인가를 구분하지 않으면 로그인만 된 사용자가 다른 사용자의 데이터에 접근할 수 있다.
  • 권한 검증을 화면이나 클라이언트에만 두면 API 직접 호출로 우회될 수 있다.
  • 관리자, 소유자, 참여자처럼 역할이 섞이면 단순 role 체크만으로 부족할 수 있다.
  • 권한 실패를 인증 실패처럼 처리하면 장애 분석과 보안 로그 해석이 어려워진다.

동작 원리

  1. 요청에서 세션, 토큰, API key 같은 인증 정보를 읽는다.
  2. 인증 정보를 검증해 사용자 식별자와 기본 권한 정보를 만든다.
  3. 요청한 리소스의 소유자, 상태, 조직, 역할 같은 접근 조건을 확인한다.
  4. 조건을 만족하면 요청을 처리하고, 아니면 명확한 실패 응답을 반환한다.
  5. 권한 실패는 감사 로그나 보안 이벤트로 남긴다.

실무 판단 기준

상황선택이유
로그인하지 않은 요청401 Unauthorized신원을 확인할 수 없다
로그인했지만 권한 부족403 Forbidden신원은 확인했지만 접근 권한이 없다
본인 리소스 접근사용자 id와 리소스 소유자 비교role만으로 소유권을 보장할 수 없다
관리자 기능role + 기능 단위 권한관리자 role 하나에 모든 권한을 몰면 위험하다
내부 API호출 주체와 사용 목적 검증내부망에 있다는 이유만으로 신뢰하면 안 된다

자주 나는 실수

  • 로그인 여부만 확인하고 리소스 소유권을 확인하지 않는다.
  • 프론트엔드 메뉴 노출 여부를 권한 검증으로 착각한다.
  • userId를 요청 body나 path에서 받은 값 그대로 신뢰한다.
  • 401과 403을 구분하지 않아 문제 원인을 숨긴다.
  • 관리자 권한을 너무 넓게 부여하고 사용 이력을 남기지 않는다.

확인 방법

  • 테스트: 다른 사용자의 리소스 id로 조회, 수정, 삭제가 막히는지 확인한다.
  • 테스트: 권한 없는 role이 관리자 API를 호출할 때 403이 반환되는지 확인한다.
  • 로그: 사용자 id, 요청 리소스, 거부 사유, trace id를 남긴다.
  • 리뷰: Controller, Service, Query 조건 중 어디서 권한이 보장되는지 확인한다.

장점과 한계

장점한계
인증과 인가 책임을 분리하면 누락 지점을 찾기 쉽다리소스별 권한 조건이 복잡해질 수 있다
401과 403을 구분하면 클라이언트 대응과 로그 분석이 명확해진다너무 자세한 실패 사유는 공격자에게 힌트가 될 수 있다
소유권 검증을 서버에서 강제하면 API 우회를 막을 수 있다모든 조회 경로에 일관되게 적용해야 한다

짧은 예제

public OrderDetail getOrder(long orderId, AuthenticatedUser user) {
    Order order = orderRepository.findById(orderId)
        .orElseThrow(() -> new NotFoundException("order not found"));
 
    if (!order.isOwnedBy(user.id()) && !user.hasRole("ORDER_ADMIN")) {
        throw new ForbiddenException("order access denied");
    }
 
    return OrderDetail.from(order);
}

요청의 userId를 그대로 신뢰하지 않고, 인증된 사용자와 조회한 리소스의 소유권을 서버에서 비교한다.

핵심 요약

인증은 사용자를 식별하는 과정이고 인가는 식별된 사용자의 접근 가능 여부를 판단하는 과정이다.

로그인 여부만 확인하는 것은 권한 검증이 아니다.

백엔드 API는 클라이언트 화면 노출 여부와 별개로 항상 권한을 검증해야 한다.

본인 데이터 접근은 role보다 리소스 소유권 비교가 핵심이다.

401은 인증 실패, 403은 인가 실패로 구분하는 것이 운영과 디버깅에 유리하다.

권한 실패는 보안 이벤트로 볼 수 있으므로 trace id와 거부 사유를 남긴다.

꼬리 질문

  • 인증과 인가의 차이를 실무 예시로 설명할 수 있는가?
  • 로그인한 사용자가 다른 사용자의 주문을 조회하지 못하게 하려면 어디서 검증해야 하는가?
  • 401과 403은 언제 각각 반환해야 하는가?

관련 문서