HTTP 명세는 아쉽게도 이름을 잘못 붙였습니다. 401은 "Unauthorized(미승인)"라고 불리지만 실제로는 미인증을 의미합니다—서버가 당신이 누구인지 모른다는 뜻입니다. 진짜 인가 실패는 403 "Forbidden(금지)"입니다—서버는 당신이 누구인지 정확히 알고 있으며, 그 행동을 할 수 없다고 결정한 것입니다.
이 명명 혼란은 거의 다른 어떤 HTTP 오해보다 더 많은 API 버그를 일으킵니다. 이 구분을 한 번 명확히 이해하고 나면, 두 번 다시 혼동하지 않을 것입니다.
건물 보안 비유
이것은 단순한 비유가 아닙니다—인증과 인가가 실제로 작동하는 방식입니다:
401 Unauthorized: 당신은 ID 배지 없이 문 앞에 서 있습니다. 보안 요원은 당신이 누구인지 모릅니다. 당신의 신원을 모르기 때문에 보안 등급을 확인할 수 없습니다. 먼저 배지를 보여주세요.
403 Forbidden: 당신은 ID 배지가 있습니다. 보안 요원은 당신이 엔지니어링 부서의 Alice라는 것을 압니다. 하지만 당신은 임원 층에 들어가려고 하는데, 엔지니어링 부서의 Alice는 출입 목록에 없습니다. 배지를 아무리 다시 보여줘도 달라지지 않습니다.
보안 요원은 항상 권한을 확인하기 전에 신원을 먼저 확인합니다. 인증이 인가에 선행합니다. 언제나.
403을 받으면: 재시도하지 마세요. 문제는 인증 정보가 아니라 권한입니다. 사용자에게 오류 메시지를 보여주세요. 사용자가 실제로 접근할 수 있는 곳으로 안내하세요.
if (response.status === 403) {
showError("You don't have permission to do this");
redirectToHome();
// 재시도하지 마세요. 도움이 되지 않습니다.
}
결정 과정
요청이 들어오면:
인증 정보가 있습니까? 없음 → 401
인증 정보가 유효합니까? 아니오 → 401
이 사용자에게 권한이 있습니까? 아니오 → 403
그 외의 경우 → 요청 처리
인증은 인가보다 먼저 이루어집니다. 신원을 확인하지 않은 사람의 권한을 확인할 수는 없습니다.
전체 예시
관리자 전용 엔드포인트:
// 인증 정보 없음
POST /api/admin/users HTTP/1.1
→ 401 Unauthorized
// 유효한 인증 정보, 일반 사용자
POST /api/admin/users HTTP/1.1
Authorization: Bearer token-for-alice
→ 403 Forbidden
// 유효한 인증 정보, 관리자 사용자
POST /api/admin/users HTTP/1.1
Authorization: Bearer token-for-admin
→ 201 Created
GET /api/documents/secret-id HTTP/1.1
Authorization: Bearer valid-token
// 옵션 1: 솔직하게
→ 404 Not Found (리소스가 존재하지 않음을 드러냄)
// 옵션 2: 불투명하게
→ 403 Forbidden (존재 여부를 숨김)
존재하지 않는 리소스에 403을 사용하면 열거 공격을 방지할 수 있지만, API 투명성은 낮아집니다. 보안 요구사항에 따라 선택하세요.
401과 403에 관한 자주 묻는 질문
401이 미인증을 의미한다면 왜 "Unauthorized(미승인)"라고 불릴까요?
역사적인 우연입니다. 1996년 HTTP/1.0이 정의될 당시에는 용어가 지금처럼 정확하지 않았습니다. "Unauthenticated(미인증)"가 더 명확하다는 것을 사람들이 깨달았을 때, 이미 그 이름은 수많은 시스템에 깊이 자리 잡고 있었습니다. 명세는 혼란스러운 이름을 그대로 안고 있지만, 여러분은 그것에 혼란스러울 필요가 없습니다.
만료된 토큰에 대해 401을 반환해야 합니까, 아니면 403을 반환해야 합니까?
401입니다. 만료된 토큰은 유효하지 않은 인증입니다—서버는 더 이상 유효하지 않은 인증 정보로는 신원을 확인할 수 없습니다. 클라이언트는 토큰을 갱신하고 재시도해야 합니다.
API 키는 어떻습니까? 인증입니까, 아니면 인가입니까?
API 키는 인증입니다—신원을 증명합니다("이 요청은 애플리케이션 X에서 온 것입니다"). API 키가 없거나 유효하지 않으면 401을 반환하세요. API 키가 유효하지만 이 작업에 대한 권한이 없으면 403을 반환하세요.
리소스가 존재하지 않는다는 것을 숨기기 위해 403을 사용할 수 있습니까?
네, 하지만 절충점을 이해해야 합니다. 404 대신 403을 반환하면 공격자가 열거를 통해 유효한 리소스 ID를 발견하는 것을 막을 수 있습니다. 하지만 정당한 사용자에게는 디버깅이 더 어려워집니다. 대부분의 API는 존재하지 않는 리소스에 404를 사용하고, 실제 권한 거부에는 403을 씁니다.