지난 포스팅에서는 HTTP 메서드의 활용을 마지막으로 GET
POST
PUT
PATCH
DELETE
가 실제로 어떻게 사용되는지 다양한 예시들을 살펴보았다.
이번 포스팅에서는 HTTP 상태코드에 대해 알아보고, HTTP 리다이렉션과 PRG에 대해서도 간단히 살펴보도록 하자.
📌 HTTP Status Code ?
- HTTP 응답 상태 코드는 특정 HTTP 요청이 성공적으로 완료되었는지 알려준다. 즉, 클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능이다.
MDN Webdocs 에서 상태코드에 대한 정의를 일부 발췌해왔다.
사실, 우리는 이번 HTTP 시리즈의 포스팅에서 수많은 메시지들을 예시로 확인했으며, 그 중 응답 메시지의 Status-line
에 상태코드가 함께 전달되는 모습을 기억하고 있을 것이다.
위 그림에서 200 OK
라고 적혀있는 부분이 바로 오늘 다루게 될 HTTP 상태코드이며, 앞서 발췌한 정의에서 알 수 있듯이 클라이언트의 요청에 대한 처리 상태를 알려주는 역할을 수행한다.
따라서 클라이언트는, 요청을 보낸 후 서버로부터 받은 응답 메시지의 상태코드를 참고하여 자신의 요청이 정상적으로 처리되었는지를 확인할 수 있는 것이다.
또한, 상태코드는 다음과 같이 5 개의 그룹으로 나뉘어 관리된다.
📌 5 Groups of HTTP Status Code
1xx
(Informational)2xx
(Successful)3xx
(Redirection)4xx
(Client Error)5xx
(Server Error)
각각의 그룹에 대해 간단히 설명하자면,
1xx
는 100 번대의 상태코드로, 요청이 수신되어 처리 중이라는 의미를 가진다.
잘 사용되지 않는 상태코드이기 때문에 본 포스팅에서는 자세히 다루지 않았다.
2xx
는 200 번대의 상태코드로, 요청이 정상적으로 처리되었다는 의미를 가진다.
위 예시 그림에서 200 OK
라는 상태코드를 응답으로 받았으므로, 클라이언트의 요청은 정상적으로 수행되었다는 것을 알 수 있다.
3xx
는 300 번대의 상태코드로 리다이렉션을 의미하며, 이는 요청을 완료하려면 추가적인 작업이 필요함을 의미한다. 리다이렉션에 대해서는 이후 다루게 될 것이다.
4xx
는 400 번대의 상태코드로 클라이언트 오류를 의미하며, 잘못된 문법 등의 오류로 인해 서버가 요청을 수행할 수 없고 그 원인이 클라이언트에게 있음을 뜻한다.
5xx
는 500 번대의 상태코드로 서버 오류를 의미하며, 400 번대와 동일하게 오류로 인한 요청 처리 실패를 의미하지만 원인이 서버에게 있음을 뜻한다.
이 때, 각 상태코드의 첫 번째 자리는 최상위 코드가 되어 이를 기준으로 분류되고, 이후에 따라오는 숫자들은 동일한 기능을 수행하지만 내부적인 동작이나 원인에 있어 차이를 가지게 된다.
즉, 403 과 404 의 서로 다른 상태코드가 클라이언트 오류를 의미하는 것은 동일하지만, 그 세부적인 원인은 다르다고 볼 수 있는 것이다.
따라서, 클라이언트가 이해할 수 없는 상태코드를 서버로부터 반환받게 되더라도 최상위 코드로 해석해서 처리하는 것이 가능하다. 또한, 미래에 새로운 상태코드가 추가된다고 하더라도 최상위 코드는 5 개 그룹 내에 포함될 것이기 때문에 클라이언트를 굳이 변경하지 않아도 된다. 최상위 코드를 기준으로 이해할 수 있기 때문이다.
그럼 이제부터 본격적으로 각각의 상태코드 그룹에 대해 세부적으로 알아보자.
2xx
의 상태코드는 클라이언트의 요청이 정상적으로 처리되었다는 의미이다.
2xx
에서 자주 사용되는 대표적인 상태코드는 아래와 같다.
📌
2xx
Status Code
200 OK
201 Created
202 Accepted
204 No Content
200 OK
200 OK
는 자주 접하게 될 상태코드로, 단순히 요청이 성공적으로 수행되었음을 의미한다.GET
으로 요청한 후, 그에 대한 응답을 성공적으로 보내면서 200 OK
의 상태코드를 함께 전송하는 모습을 확인할 수 있다.201 Created
201 Created
는 요청이 성공적으로 수행되었으며, 이에 따라 새로운 리소스가 정상적으로 생성되었음을 의미한다.
즉, POST
를 활용하여 신규 리소스를 생성하는 요청에서 사용하게 되며, 이 때 서버는 생성된 신규 리소스의 URL
을 Location
필드에 담아 함께 전송해준다.
위 예시에서는 클라이언트가 '/members' 컬렉션에 POST
로 신규 리소스를 생성하는 요청을 전달했고, 서버가 신규 리소스를 성공적으로 생성한 뒤, 201 Created
상태코드를 함께 담아 전송하는 모습을 확인할 수 있다.
이 때, 빨간 화살표가 가리키는 응답 메시지 헤더의 Location
필드에는 신규 리소스가 생성된 URL
이 담겨 있다.
202 Accepted
202 Accepted
는 요청이 성공적으로 접수되었으나, 아직 처리가 완료되지 않았음을 의미한다.
예를 들면, 대량의 작업을 정해진 시간에 일괄적으로 처리하기 위한 배치 처리에서 주로 사용한다.
이러한 경우, 요청을 접수하고 설정된 배치 처리 시간까지 대기하여야 하기 때문에 배치 프로세스가 요청을 수행할 때까지는 처리 완료 응답을 전송할 수 없을 것이다.
따라서, 단순히 요청이 성공적으로 접수되었다는 의미로, 202 Accepted
상태코드를 사용하게 된다.
204 No Content
204 No Content
는 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 담을 데이터가 없음을 의미한다.
보통, GET
이나 POST
를 활용한 클라이언트의 요청이 성공적으로 수행되고 나면, 서버는 응답 메시지의 Body
에 결과에 대한 데이터를 담아 전송한다.
예를 들어, GET
을 통한 조회 요청에서는 조회 결과 데이터를 담아 응답 메시지를 전송하고, POST
를 통한 생성 요청에서는 생성된 신규 리소스를 응답 메시지에 담아 전송해주는 식이다.
하지만, 클라이언트의 요청을 수행하고 난 뒤, 서버가 응답 메시지의 Body
에 담을 데이터가 없는 경우가 있을 수 있다.
이러한 경우에는 204 No Content
를 전송함으로서, 요청이 성공적으로 수행되었으나 Body
에 담아 전송할 데이터가 없다는 것을 클라이언트에게 명시해준다.
좋은 예로는, 웹 문서 편집기의 SAVE 버튼을 들 수 있다.
현재까지 작성한 내용을 단순히 저장만 하면 되기 때문에 서버는 SAVE 의 결과로 어떠한 데이터도 전송해줄 필요가 없다.
또한, SAVE 버튼을 클릭하더라도 현재와 같은 화면을 유지해야 하기 때문에 페이로드 본문에는 특별한 데이터가 담기지도 않는다.
결론적으로, 클라이언트는 본문에 아무런 데이터가 담겨있지 않더라도, 204 No Content
만으로 요청의 성공을 인지할 수 있게 되는 것이다.
3xx
의 상태코드는 클라이언트의 요청을 완료하기 위해 유저 에이전트의 추가 조치가 필요하다는 의미이다.
여기서 이야기하는 유저 에이전트는 주로 웹 브라우저를 가리킨다.
즉, 클라이언트의 요청을 성공적으로 완료하기 위해서는 클라이언트 단의 유저 에이전트에서 추가적인 작업이 필요하고, 서버에서는 3xx
상태코드로 이를 알려주어 유저 에이전트가 추가 조치를 취할 수 있도록 돕는 것이다.
3xx
에서 자주 사용되는 대표적인 상태코드는 아래와 같다.
📌
3xx
Status Code
300 Multiple Choices
301 Moved Permanently
302 Found
303 See Other
304 Not Modified
307 Temporary Redirect
308 Permanent Redirect
이 중, 300 Multiple Choices
는 요청에 대해서 다수의 응답이 가능하며, 유저 에이전트가 그 중 하나를 반드시 선택하여야 한다는 의미인데 실무에서는 자주 사용되지 않는다고 한다.
따라서 아래에서는, 301
부터 308
의 상태코드에 대해 설명하고자 한다.
먼저, 각 상태코드들에 대한 이해를 돕기 위해 리다이렉션을 간단히 살펴보도록 하자.
리다이렉션이란 무엇일까?
이에 대한 MDN Webdocs 의 정의를 가져와보았다.
📌 리다이렉션 (Redirection)
- 페이지 단위의 실제 리소스, 폼 혹은 전체 웹 애플리케이션이 다른 URL에 위치하고 있는 상태에서 링크를 존속시키는 기술
즉, 리다이렉트는 클라이언트가 요청한 URL
에 대해 다른 URL
을 다시(re) 지시(direct)하여 새로운 주소로 이동할 수 있게 하는 기술이다.
아래 예시 그림을 보면,
클라이언트는 '/event' 라는 URL
을 웹서버에 전송하여 이벤트 페이지에 대한 접속을 요청하고 있다.
하지만, '/event' 는 더 이상 사용하지 않는 URL
이며, 현재는 '/new-event' 를 사용하고 있다고 가정해보자.
이 때, 웹서버는 '/event' 를 요청한 클라이언트에게 3xx
의 리다이렉션 상태코드와 함께 헤더의 Location
필드에 새로운 URL
인 '/new-event' 를 담아 응답메시지를 전송한다.
응답메시지를 전달받은 클라이언트는 3xx
상태코드와 Location
필드의 URL
을 참고하여 웹서버의 새로운 URL
로 리다이렉션하라는 지시를 이해할 수 있다.
이후 클라이언트는 웹서버의 리다이렉션 지시에 따라 새로운 URL
에 대한 접속을 요청하게 되고, 웹서버는 200 OK
와 함께 이벤트 페이지의 html
을 전송해주게 된다.
정리하면, 클라이언트가 요청한 URL
에 대해 웹서버가 접속을 거부하고 싶거나 혹은 새로운 URL
을 사용하고 있는 환경일 때, 웹서버가 클라이언트를 다른 URL
로 이동시킬 수 있게 하는 기술이 바로 리다이렉션인 것이다.
또한, 리다이렉션은 크게 3 가지로 나눌 수 있다.
📌 리다이렉션의 종류
- 영구 리다이렉션
- 일시 리다이렉션
- 특수 리다이렉션
먼저, 영구 리다이렉션은 특정 리소스의 URL
이 영구적으로 이동한 것을 의미한다.
앞선 예시처럼, 이벤트 페이지의 URL
이 새로운 URL
로 변경된 것도 영구 리다이렉션에 해당한다고 볼 수 있다.
두 번째로, 일시 리다이렉션은 말그대로 특정 리소스의 URL
이 일시적으로 이동한 것을 의미한다.
이는 주문 완료 후 주문 내역 화면으로 이동하는 경우가 해당되며, 이후 살펴볼 PRG 를 통해 클라이언트의 중복 요청을 예방하기 위한 목적으로 활용되기도 한다.
마지막, 특수 리다이렉션은 클라이언트가 가지고 있는 캐시 기간이 만료되었는지를 확인하고, 서버가 이를 확인하여 데이터를 직접 전송해줄 것인지 혹은 클라이언트가 캐시를 활용할 수 있도록 할 것인지를 판단하는 것을 의미한다.
위와 같이 리다이렉션은 3 가지의 종류로 분류될 수 있고, 각 종류에 따라 사용하는 상태코드가 각각 달라진다.
이제, 리다이렉션의 종류를 기준으로 301
부터 308
의 상태코드들에 대해 하나씩 알아보도록 하자.
301 Moved Permanently
, 308 Permanent Redirect
- 영구 리다이렉션영구 리다이렉션은 리소스의 URL
이 영구적으로 이동한 것으로, 이전의 URL
을 영구적으로 사용하지 않는 것을 말하며,
이 때는 301 Moved Permanently
와 308 Permanent Redirect
를 사용할 수 있다.
먼저, 301 Moved Permanently
는 리다이렉트 시, 요청 메서드가 GET
으로 변하고, 본문이 제거될 수 있음을 의미한다.
위 예시에서 클라이언트는 '/event' 의 이벤트 페이지에 'name' 과 'age' 정보를 POST
메서드를 활용하여 생성하려고 한다.
이 때, 웹서버는 301 Moved Permanently
상태코드와 Location
필드를 활용하여 이벤트 페이지의 주소가 '/new-event' 라는 새로운 주소로 영구적 변경되었다는 사실을 알리고, 리다이렉트를 지시한다.
이 경우, 301
상태코드는 요청 메서드를 GET
으로 변경시키고 본문을 제거하기 때문에 클라이언트가 재요청한 메시지는 '/new-event' 에 대한 GET
요청 메시지로 변경되어 웹서버에 전송된다.
POST
메서드가 GET
으로 변경되고, 'name' 과 'age' 정보는 본문에 해당하므로 제거되었기 때문이다.
따라서 클라이언트는, 단순히 웹서버에게 이벤트 페이지의 조회 요청을 보낸 것이 되고, 본문 정보를 다시 작성하여 생성 요청을 보내야 할 것이다.
여기서 301
상태코드가 무조건적으로 요청 메서드를 변경시키며, 본문을 제거하는 것이 아니라는 점에 주의하자. 이는 브라우저가 301
상태코드에 대한 작업을 어떻게 구현해놓았는지에 따라 다를 수 있다.
하지만, 거의 대부분의 브라우저는 요청 메서드를 GET
메서드로 변경시키고 본문을 제거하도록 구현하였으므로 위 그림과 같이 수행될 가능성이 높다.
다음은 308 Permanent Redirect
이다.
308 Permanent Redirect
는 301
과 기능은 동일하지만, 리다이렉트 시 요청 메서드와 본문을 유지하게 된다.
즉, 클라이언트가 처음에 POST
메서드와 함께 생성할 리소스 정보를 Body
에 담아 전송하였다면, 새로운 URL
로 리다이렉트하더라도 그 메서드와 Body
내용이 유지되는 것이다.
위 그림은 앞선 예시와 동일하지만, 301
이 아닌 308
상태코드를 사용하고 있다.
이 때, 4 번 요청 단계를 자세히 살펴보면, 클라이언트가 처음 사용했던 POST
메서드가 유지되고, 'name' 과 'age' 정보가 본문에 유지되어 있는 모습을 확인할 수 있다.
즉, 웹서버가 301
을 사용하였을 때 메서드가 변경되고 본문이 제거되어 단순 조회 요청으로 전송되었던 것과는 달리, 308
을 사용하면 요청메시지의 정보가 변하지 않고 새로운 URL
에 같은 요청을 재전송할 수 있는 것이다.
이는 308
상태코드를 사용하였을 경우, 사용자가 본문 내용을 처음부터 다시 작성하지 않더라도 자동적으로 새로운 URL
에 요청을 전송할 수 있음을 의미한다.
이렇게, 301 Moved Permanently
와 308 Permanent Redirect
는 동일하게 영구적 리다이렉트 요청 기능을 수행하지만, 메서드를 GET
으로 변경하고 본문 내용을 삭제하느냐에 있어 중요한 차이점을 가지게 된다.
그렇다면, 왜 대부분의 브라우저는 리다이렉트 시 GET
메서드로 변경시키고 본문 내용을 삭제하도록 구현해놓았을까?
308
상태코드처럼, 리다이렉트 시 초기의 요청메시지 정보를 유지할 수 있도록 구현했다면 본문 내용을 다시 작성하여 요청을 전송하지 않더라도 자동으로 URL
이 변경되어 요청을 전달할 수 있을 것인데 말이다.
사실 이것은 HTTP 리다이렉션에 대한 스펙이 공개되었을 때, 대부분의 브라우저가 메서드를 변경시키고 본문을 삭제하는 방식으로 구현해놓았기 때문이다. 이는 나중에야 밝혀진 사실이지만, 사실 HTTP 측의 의도는 초기 클라이언트의 메서드와 본문 내용을 유지하는 방식으로 리다이렉션을 설계하는 것이었다고 한다. 하지만, 이미 대부분의 브라우저들이 스펙을 오해하고 다른 방식으로 설계하였기 때문에 현재는 GET
메서드로의 변경과 본문 삭제가 거의 모든 브라우저에서의 기본적 리다이렉션 형태가 되었다.
또한, 새로운 URL
로 변경되었을 때는 웹페이지에서 요구하는 데이터도 변경되었을 가능성이 높다. 즉, 이전 URL
에 맞추어 작성된 본문 내용이 새로운 URL
에서도 정확하게 입력되어 요청이 정상적으로 수행될 것이라는 보장이 없는 것이다.
따라서, 기존 POST
메서드를 GET
메서드로 변경하고 본문 내용을 다시 작성하는 것이 오히려 안전하고, 웹서버 입장에서는 요청 실패건수를 미리 줄일 수 있어 기본적으로 사용된다.
302 Found
, 307 Temporary Redirect
, 303 See Other
- 일시 리다이렉션일시 리다이렉션은 리소스의 URL
이 일시적으로 변경된 것을 말하며,
이 때는 302 Found
와 307 Temporary Redirect
, 303 See Other
의 세 가지 상태코드를 사용할 수 있다.
먼저, 302 Found
는 리다이렉트 시, 요청 메서드가 GET
으로 변하고 본문이 제거될 수 있음을 의미한다. 이는 앞서 살펴본 영구 리다이렉션의 301 Moved Permanently
와 동일하다.
하지만 이러한 302 Found
는 무조건적으로 메서드를 변경하고 본문을 제거하지는 않기 때문에 브라우저에 따라 작업 수행이 달라지는 불확실성의 위험이 존재한다. 따라서 이를 확실하게 하기 위해 307
과 303
상태코드가 추가되면서 절대적인 메서드와 본문 유지 보장, 절대적인 메서드 변경 및 본문 제거의 보장이 가능해지게 되었다.
우선 307 Temporary Redirect
는 리다이렉트 시, 요청 메서드와 본문을 유지한다. 물론, 일시적 리다이렉션 요청 기능을 수행한다는 점에서는 302 Found
와 같다.
303 See Other
또한 302 Found
와 마찬가지로 일시적 리다이렉션 요청 기능을 수행하지만, 리다이렉트 시, 요청 메서드가 GET
으로 변경되고, 본문이 제거된다. 이는 302 Found
와 다르게 요청 메서드의 변경과 본문 제거를 무조건적으로 보장한다.
물론, 이렇게 302 Found
의 불확실성 때문에 307 Temporary Redirect
와 303 See Other
가 추가되었고 사용이 권장되고 있지만, 대부분의 브라우저가 이미 메서드 변경과 본문 삭제를 지원하고 있기 때문에 아직도 실무에서는 302 Found
를 많이 사용하고 있고 전혀 문제가 없다고 한다.
그렇다면, 일시 리다이렉션은 도대체 언제 사용하는 것일까?
일시 리다이렉션이 필수적으로 필요한 PRG에 대해 간단히 살펴보도록 하자.
- PRG 는 일시적인 리다이렉션에서 중복 요청의 전송을 방지하기 위해 사용하는 패턴이다.
만약, POST
메서드를 이용해 주문을 생성하고, 이후 웹 브라우저를 리프레시하였다고 가정해보자.
리프레시는 이전 요청을 재전송하기 때문에 POST
메시지를 다시 전송하게 되고, 따라서 서버에 중복 주문이 들어가게 될 가능성이 있다.
이를 해결하기 위해 사용하는 것이 바로 PRG 이다.
PRG 는 주문 후에 리프레시로 인한 중복 주문을 방지할 수 있는데, POST
를 사용한 주문 이후에 주문 결과 화면을 GET
메서드로 리다이렉트하기 때문이다.
따라서, PRG 를 사용하게 되면 주문 이후에 리프레시를 여러 번 반복하게 되더라도 주문 결과 화면만을 GET
요청으로 조회하게 되기 때문에 중복 주문을 방지할 수 있게 된다.
주로 배달 주문 어플이나 온라인 쇼핑 애플리케이션에서 주문이 끝난 후, 자동으로 주문이 완료되었음을 알리는 결과 화면으로 이동하게 되는 동작들이 PRG 의 사례들이 될 것이다.
PRG 에 대한 시각적인 이해를 위해 예시를 살펴보자.
먼저, PRG 를 사용하지 않은 예시이다.
클라이언트는 주문창에서 마우스와 수량 1 개를 선택했고, 이를 POST
메서드로 전송했다.
서버에서는 클라이언트의 요청을 받아 데이터베이스에 저장하면서, 새로운 주문을 성공적으로 생성하여 200 OK
를 반환하고 있다.
이 때, 클라이언트가 웹 브라우저를 리프레시하였고, 이전 요청이 그대로 재전송되면서 같은 주문이 중복되어 생성되는 문제가 발생하였다. 물론, 클라이언트나 서버 단에서 이를 방지하기 위한 설계를 구현하는 것이 기본이지만 예시에서는 구현되어있지 않다고 가정했다.
그렇다면, PRG 를 사용한 예시는 어떨까?
클라이언트는 이전과 마찬가지로 마우스와 수량 1 개를 선택해 POST
메서드로 주문을 생성했다.
서버는 클라이언트의 요청을 받아 데이터베이스에 주문을 생성하고, 302 Found
상태코드를 반환하였다. 이는 Location
필드의 주문 결과 화면 URL
로 리다이렉트하라는 지시와 같다.
302 Found
는 메서드를 GET
으로 변경하고, 본문 내용을 제거하기 때문에 클라이언트는 주문 결과 화면에 대해 단순 조회 요청을 전송하게 된다.
이제 주문 결과 화면으로 이동하게 된 클라이언트는, 리프레시를 반복하더라도 주문 결과 화면에 대한 조회 요청만을 반복적으로 전송하게 된다.
이는 최종적으로, 중복 주문 요청을 방지할 수 있다.
위와 같이, PRG 는 302 Found
혹은 303 See Other
의 일시 리다이렉션 상태코드를 활용하여 POST
메서드를 GET
메서드로 변경했고, 이는 클라이언트의 리프레시로 인한 중복 주문을 방지하는 효과를 가져왔다.
즉, POST
요청을 주문 결과 화면으로 리다이렉션하여 GET
요청으로 변경시킨 것이다.
이는 POST , Redirect , GET 을 따서 PRG 라 불리며, 일시 리다이렉션을 활용하는 좋은 사례라 볼 수 있다.
⛔ 지금까지 영구 리다이렉션의 상태코드 301
, 308
과 일시 리다이렉션의 상태코드 302
, 307
, 303
에 대해 살펴보았다. 또한, 일시 리다이렉션이 유용하게 활용되는 PRG 예시까지 살펴보면서 그 필요성에 대해서도 확인해보았다.
이제, 나머지 상태코드에 대해 알아보면서 3xx
상태코드 설명을 마무리해보자.
304 Not Modified
- 특수 리다이렉션특수 리다이렉션은 캐시를 목적으로 활용된다.
즉, 304 Not Modified
상태코드를 통해 클라이언트가 요청한 리소스가 수정되지 않았으니 캐시에 가지고 있는 리소스를 그대로 사용해도 된다는 의미를 가진다.
따라서, 304
를 전달받은 클라이언트는 자신의 로컬에 저장된 캐시에서 리소스를 재사용할 수 있게 되고, 이를 통해 네트워크 다운로드 용량을 효과적으로 줄일 수 있다.
주의할 점은 304
응답 메시지는 Body
본문에 어떠한 데이터도 포함해서는 안된다는 것이다. 이는 클라이언트가 로컬에 있는 캐시에서 리소스를 가져와 사용하여야 하기 때문이다.
4xx
상태코드는 클라이언트 요청의 잘못된 문법 등으로 서버가 요청을 수행할 수 없음을 의미한다.
즉, 클라이언트 오류를 의미하며, 클라이언트가 이미 잘못된 요청을 보내고 있기 때문에 이러한 경우에는 똑같은 재요청이 실패하게 된다.
따라서, 4xx
상태코드가 반환된 경우에는 클라이언트가 요청을 수정하여 재전송하여야 한다.
4xx
에서 주로 사용되는 상태코드들은 다음과 같다.
📌
4xx
Status Code
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
400 Bad Request
400 Bad Request
는 클라이언트의 잘못된 요청으로 서버가 요청을 수행할 수 없음을 의미한다.
주로 요청 구문, 메시지 등의 오류로 인한 문제가 해당되며 요청 파라미터가 잘못되거나 API 스펙이 맞지 않는 경우에도 400
상태코드를 사용한다.
따라서 이를 해결하기 위해서는 클라이언트가 자신의 요청을 검토하고 재전송하여야 한다.
401 Unauthorized
401 Unauthorized
는 클라이언트가 해당 리소스에 대한 인증이 필요하다는 의미이다.
즉, 클라이언트가 인증되지 않아 요청을 수행하지 못했으니 인증 과정을 거쳐 요청을 재전송하면 해결할 수 있다.
다만, 인증(Authentication)과 인가(Authorization)의 개념을 정확하게 알고 있다면 401
이 왜 Unauthorized
인지 납득하지 못할 수 있다.
분명 401
은 인증이 필요하다는 의미인데 Unauthenticated
가 아닌 Unauthorized
를 사용하고 있기 때문이다.
📌 인증(Authentication)과 인가(Authorization)
- 인증(Authentication) : 본인이 누구인지 확인 (로그인)
- 인가(Authorization) : 특정 리소스에 권한이 있는지 확인 (권한)
- 즉, 인증되었다고 하더라도, 인가되지 않았다면 리소스에 접근할 수 없다.
따라서, 이를 헷갈리지 않는 것이 중요하다. 401 Unauthorized
는 인가가 아닌 인증이 필요함을 의미하며 클라이언트가 누구인지 확인되지 않았음을 뜻한다.
추가적으로, 401 Unauthorized
응답 메시지에서는 WWW-Authenticate
헤더와 함께 상세한 인증 방법을 설명하고 있으니 이를 참고하여 인증을 거쳐 요청을 재전송하면 된다.
403 Forbidden
이전 401 Unauthorized
상태코드는 인증이 필요하다는 의미의 응답이었다.
반면, 403 Forbidden
상태코드는 클라이언트가 인증되었으나, 인가되지 않았다는 의미를 가진다.
즉, 인증 자격은 증명되었으나, 접근 권한이 불충분하여 서버가 요청의 승인을 거부했음을 의미하는 것이다.
따라서, 주로 admin 등급이 아닌 사용자가 admin 등급의 리소스에 접근을 요청하였을 때 403 Forbidden
메시지를 응답받게 된다.
404 Not Found
404 Not Found
는 인터넷을 사용하다보면 자주 마주치는 반가운 상태코드다.
이는 간단히 정리해서 클라이언트가 요청한 리소스를 찾을 수 없음을 의미한다.
클라이언트가 특정 리소스를 서버에 요청했지만, 서버에서는 해당 리소스가 존재하지 않아 응답해줄 수 없는 것이다.
물론 404
응답을 마주쳤다고 해서 무조건적으로 해당 리소스가 서버에 존재하지 않는다는 의미는 아니다.
서버가 클라이언트의 특정 리소스 접근을 막고자 하는 경우에 의도적으로 404
를 사용하는 경우가 있기 때문이다.
이러한 경우, 403
을 반환하여 클라이언트에게 권한이 없음을 알리고 리소스 접근을 막아낼 수 있지만, 리소스의 존재 자체를 완전히 숨기고 싶은 경우에는 404
를 반환하여 처리하기도 한다.
5xx
상태코드는 서버의 문제로 오류가 발생하여 요청을 정상적으로 처리할 수 없음을 의미한다.
즉, 서버 오류를 의미하며, 오류의 원인이 서버에 있기 때문에 서버가 복구되면 같은 요청을 재전송하였을 때 성공할 가능성이 있다.
이는 이전의 4xx
상태코드와 5xx
상태코드를 구분하는 가장 큰 차이점이다.
4xx
는 클라이언트의 요청에 문제가 있는 것이기 때문에 요청 메시지를 검토하여 수정한 뒤 재전송하여야 하는 반면, 5xx
는 서버에 문제가 있는 것이기 때문에 시간이 지나 서버가 복구되면 같은 요청 메시지를 재전송하더라도 요청이 성공할 가능성이 있다.
5xx
에서 주로 사용되는 상태코드들은 다음과 같다.
📌
5xx
Status Code
500 Internal Server Error
503 Service Unavailable
500 Internal Server Error
500 Internal Server Error
는 말 그대로, 서버 내부의 문제로 인해 오류가 발생했음을 의미한다.
따라서, 백엔드에서는 애매한 서버 문제들에 대해서 대부분 500
오류로 처리한다고 한다.
503 Service Unavailable
503 Service Unavailable
은 서비스 이용 불가를 의미한다.
이는 서버가 일시적인 과부하 혹은 예정된 작업으로 인해 잠시동안 요청을 처리할 수 없는 상태일 때 사용된다.
따라서 짧은 시간에 대용량의 트래픽이 몰리는 경우, 서버가 과부하되어 503
응답을 반환하는 경우가 있을 수 있고,
특정 시간대에 서버 패치 및 업데이트 등 다양한 작업을 수행하기 위해 서버 다운을 시켜놓는 경우에도 503
응답을 반환할 수 있을 것이다.
추가적으로, 이러한 경우에는 Retry-After
헤더 필드를 사용하여 서버가 복구되기까지 남은 시간을 함께 응답해줄 수도 있다.
지금까지, 대표적인 HTTP 상태코드들에 대해 알아보았다.
상태코드는 1xx
, 2xx
, 3xx
, 4xx
, 5xx
까지 총 5 개의 최상위 코드로 분류되었으며 각각 클라이언트의 요청에 대한 처리 상태를 나타냈다.
특히, 최상위 코드 안에서는 내부적인 원인이나 동작에 따라 주로 사용되는 상태코드들이 다양하게 존재하고 있음을 알 수 있었다.
실제로는, 훨씬 더 많은 상태코드들이 사용되고 관리되며 아래 링크에서 자세한 내용을 확인할 수 있다.
또한, 3xx
상태코드에 대해 살펴보면서 리다이렉션과 PRG에 대해서도 살펴볼 수 있었다. 이는 300 번대의 상태코드들이 정확히 어떤 상황에서 활용될 수 있고, 일시 리다이렉션은 어떠한 경우에 사용되는지 이해할 수 있는 좋은 예시였다.
이렇게 HTTP 상태코드에 대한 포스팅을 마치고,
다음 포스팅에서는 HTTP 메시지 헤더들을 하나씩 살펴볼 예정이다.