...
4XX Client Error
4xx 번대의 상태 코드들은 클라이언트 오류를 의미하며, 잘못된 문법 등의 오류로 인해 서버가 요청을 수행할 수 없고 그 원인이 클라이언트에게 있음을 뜻한다. 예를들어 잘못 구성된 요청 메세지 규칙 같은 것이 있을 수 있으며, 존재하지 않은 URL 요청도 있을 수 있다.
400 Bad Request
- Bad Request ⇢ 클라이언트가 잘못된 요청을 보냄을 의미
- 클라이언트의 잘못된 요청으로 서버가 이해할수가 없어 요청을 수행할 수 없음을 뜻한다.
- 주로 요청 구문, 메시지 등의 문법 오류로 인한 문제가 해당되며 요청 파라미터가 잘못되거나 API 스펙이 맞지 않는 경우에도 400 상태코드를 내뱉는다. 따라서 이를 해결하기 위해서는 클라이언트가 자신의 요청을 검토하고 재전송하여야 한다.
- 서버는 상태 코드와 더불어 바디에 에러 이유를 구체적으로 명시하고 응답하는 것이 좋다.
서버는 클라이언트 요청이 들어오면 바로 작업을 진행하지 않고 요청이 서버가 정의한 유효성에 맞는지 확인 후 진행한다. 만일 이러한 검증이 없다면 무작정 5XX 서버 오류를 반환하기에, 서버가 동작하기 이전 사전에 미리 예방한다는 차원으로 이해하면 된다.
📍 400 상태코드 흐름 예시
1. 클라이언트는 서버에 옳지않은 path 형식의 요청을 한다. (유효하지 않은 url)
2. 서버는 사전에 클라이언트의 잘못인걸 인지하고 400 응답을 내준다.
참고로 400 Bad Request 응답을 할때, 딸랑 상태 코드만 보내지말고, 위와 같이 오류 발생 시의 파라미터의 위치(path, query, body), 사용자 입력 값, 에러 이유를 구체적으로 명시하는 것이 좋다. 분명 클라이언트의 잘못인데 어떤 부분이 잘못되었는지 알려주면 재빠르게 클라이언트측에서 수정할 수 있기 때문이다.
401 Unauthorized
- Unauthorized ⇢ 요청자는 인증(authentication) 되지 않아 수행할 수 없음을 표현
- 클라이언트가 해당 리소스에 대한 인증이 없어 접근할 수 없다는 의미이다. (예를 들면 로그인 하지않으면 해당 서비스를 이용하지 못하는 것)
- 서버는 클라이언트에게 인증하라고 요구하는 내용의 응답을
WWW-Authenticate헤더와 함께 반환한다. 클라이언트는 이를 참고하여 인증을 거쳐 요청을 재전송하면 된다. - 참고로 401 응답은 Unauthorized 가 아닌 Unauthenticated 가 알맞는 단어이다.
사실 401 Unauthorized 상태 메세지는 잘못 명명된 단어이다.
보통 우리가 '권한'이라고 불리우는 것엔 인증(Authentication)과 인가/승인(Authorization) 두가지 단어가 존재하는데, 인증(Authentication)은 로그인과 같은 회원 인증 절차를 말하는거고, 승인(Authorization)은 회원 가입은 되었지만 등급 제한을 말하는 것이다.
따라서 401 상태 메세지는 Unauthenticated 가 더 알맞는 표현이다. 그리고 Unauthorization은 403 Forbidden 상태 코드의 개념이 된다. 이 부분은 뒤의 403 Forbidden 상태 코드에서 다시한번 다룬다.
📍 401 상태코드 흐름 예시
HTTP에는 기본(basic) 인증과 다이제트스트 인증이 존재한다. 그중 기본 인증 예시를 들어본다.
1. 클라이언트는 서버에게 이미지를 요청한다.
2. 하지만 이미지는 사이트에 회원 가입을 한 사람만 볼수 있다. 따라서 서버는 리소스와 더불어 WWW-Authenticate 헤더와 함께 401 응답을 반환하고 클라이언트에게 인증 절차를 진행하라고 알린다.
3. 브라우저에서 401 응답을 받고 사용자 이름과 비밀번호를 입력하는 화면을 띄운다.
4. 클라이언트는 사용자로 부터 ID:PASSWORD 를 입력 받은 후 base64로 인코딩하여 Authorization 헤더에 그 값을 담아 서버로 다시 보낸다.
5. 서버는 Authorization 헤더값을 디코딩하고, 비밀번호가 정확한지 확인하고, 문제 없으면 HTTP 200 OK 메시지와 함께 요청받았던 문서를 보낸다.
402 Payment Required
- 원래는 디지털 결제 시스템에 사용하기 위하여 만들어졌지만, 현재 이 상태 코드는 쓰이지 않는다.
- 나중에 사용될 것을 대비해 예약된 비표준 응답 코드
403 Forbidden
- Forbidden ⇢ 요청자는 승인(autorization)되지 않아 작업을 진행할수 없음
- 인증 자격은 증명되었으나, 접근 권한이 불충분하여 서버가 요청의 승인을 거부했음을 의미하는 것이다.
- 예를들어 회원에도 등급이 존재하는데, 만일 admin 등급이 아닌 사용자가 admin 등급의 리소스에 접근을 요청하였을 때 403 Forbidden 메시지를 응답받게 된다.
- 401 Unauthorized과 다른 점은 서버가 클라이언트가 누구인지 알고 있다는 점이다. (인증 되었으니)
📌 인증(Authentication) 과 승인(Authorization) 차이점
401 Unauthorized 상태코드에서도 한번 언급했듯이, 인증(Authentication) 과 승인(Authorization)은 비슷해 보이지만 엄연한 차이가 존재한다.
- 인증(Authentication) : 본인이 누구인지 확인 (로그인)
- 승인(Authorization) : 특정 리소스에 권한이 있는지 확인 (등급 권한)
카페나 포털 사이트를 예로들자면, 게시물을 읽으려고 포스팅 목록을 눌렀을때 '로그인이 필요합니다' 경고창과 함께 로그인 인증이 요구된다면 인증(401) 되지 않은 상황이다.
그래서 회원가입하고 로그인을 하고 게시물에 들어갈수 있게 되었는데, 이번엔 게시물의 첨부 파일을 다운받으려고 했는데, '새싹 등급 부터 다운 받을 수 있습니다' 라는 경고창이 뜬다면 승인(403) 되지 않은 상황이다. 즉, 서버 입장에서는 현재 요청자가 회원가입을 했으니 누군지는 알지만, 회원 등급에 따라 사용자는 요청한 자원에 접근한 권한이 없다고 판단하여 차단 한 것이다.
즉, 인증되었다고 하더라도, 승인되지 않았다면 리소스에 접근할 수 없다는 원리이다.
404 Not Found
- Not Found ⇢ 클라이언트가 요청한 자원이 존재하지 않음
- 서버가 요청한 URL을 찾을 수 없음을 알려주기 위해 사용한다. 정말 유명한 상태 코드.
- 404 페이지를 띄우는 링크는 대체로 브로큰 링크(broken link) 또는 데드 링크(dead link)라고 부른다.
- 다만 404 응답을 마주쳤다고 해서 무조건적으로 해당 리소스가 서버에 존재하지 않는다는 의미는 아니다. 서버는 인증받지 않은 클라이언트로부터 리소스를 숨기기 위하여 이 응답을 403 대신에 404를 전송하는 케이스도 있기 때문이다.
- 또한 404 상태 코드는 리소스가 일시적 또는 영구적으로 사라졌다는 것을 의미하지는 않다. 만일 리소스가 영구적 삭제되었다면 404 상태 코드 대신 410 Gone 상태 코드를 쓰는 것이 맞다.
📌 REST API 입장에서의 404
REST API 설계에서 404 응답을 반환해줘야 하는 경우는 크게 두가지가 존재한다.
- 경로가 존재하지 않음
- 자원이 존재하지 않음
대부분 프레임워크에서는 경로(라우팅)에 대한 에러 처리를 자동으로 해준다. 예를들어 존재하지않는 URL 요청 같은 경우 알아서 404로 응답하게 되고 이를 굳이 개발자가 관리할 필요는 없다.
그러나 자원의 경우는 개발자가 직접 처리해줘야 한다. 예를들어 GET /users/1 요청일 경우 정상적인 경로일 경우 서버에서 유저 ID 1인 사용자가 있는지 데이터베이스에 확인을 해야 한다. 만약 자원에 대한 존재 여부를 파악하지 않고 그대로 진행을 해버리면 후속 작업에서 오류가 발생할 수 있으며 이것은 5XX 서버 오류로 이어질 수 있다.
REST에선 URI가 자원이기 때문에 경로가 곧 자원이기도 하다. 따라서 경로와 자원 두가지를 모두 확인을 한뒤에 없다면 명확하게 404 응답을 해주도록 설계하여야 한다.
405 Method Not Allowed
- Method Not Allowed ⇢ 요청이 허용되지 않은 메소드임을 의미
- 요청 URL에 대해 지원하지 않은 메서드로 요청받았을 때 사용한다.
- 예를들어 어느 api에 대해서 리소스를 삭제하는 것을 금지하거나에 사용될 수 있다.
- 이때 요청한 리소스에 대해 어떤 메서드가 사용 가능한지 클라이언트에게 알려주기 위해, 응답에
Allow헤더가 포함되어야 한다. - 단, GET와 HEAD는 필수 메서드로 처리되기 때문에 405 응답으로 제한할수 없다.
📍 405 상태코드 흐름 예시
1. 클라이언트는 서버에게 OPTIONS 메소드를 통해 요청 가능한 메서드 목록을 요구한다.
2. 서버는 요청이 허용된 HTTP 메소드 목록을 Allow 헤더를 통해 반환한다.
3. 클라이언트는 서버가 허용하지 않은 메소드인 POST로 요청을 보낸다.
4. 허용되지 않은 메소드 요청이기 때문에 서버는 405 응답을 내린다.
[ allow 헤더 와 access-control-allow-methods 헤더 차이점 ]
우선 둘다 요청이 허용된 메소드 목록들을 반환하지만, access-control-allow-methods 헤더는 자바스크립트의 ajax 요청일때 응답받고, allow 헤더는 일반 HTTP 요청에 반환된다고 보면 된다.
406 Not Acceptable
- Not Acceptable ⇢ 콘텐츠 협상에 일치하는 것이 없음
- 이 응답은 서버가 서버 주도 콘텐츠 협상을 수행한 후, 사용자 에이전트에서 보낸 규격에 어떠한 콘텐츠도 찾지 못했을 때 보내는 응답이다.
- 종종 서버는 클라에게 왜 요청이 만족될 수 없었는지 알려주는 헤더를 포함시킨다.
- 단, 현업에서는 이 오류 코드를 거의 사용하지 않는다.
📍 406 상태코드 흐름 예시
1. 클라이언트는 한국어로 된 뉴스 페이지를 서버에 요청한다.
2. 클라이언트는 서버에게 이미지를 요청한다.하지만 서버는 한국어를 지원하지 않기에 해당되는 언어값이 없어 협상에 실패하게 되어 406응 응답하게 된다.
다만 이러한 상태 코드 흐름 형태는 현업에선 거의 사용되지 않는다.
서버는 사용자가 읽기 어려운 이 오류 코드를 사용하여 응답하는 대신, 관련 헤더를 무시하고 사용자에게 실제 페이지를 제공하는 쪽으로 유도하도록 설계된다. 예를들어 협상 헤더에 협상 우선순위를 지정하지 않고 딸랑 ko 만 써서 일치하는 언어 값이 없으면 406을 답하는 대신 그냥 기본 언어 페이지를 보여주는 것이다.
407 Proxy Authentication Required
- Proxy Authentication Required ⇢ 프록시 인증을 요구
- 401 Unauthorized 와 같으나, 프록시 버전이라고 보면 된다. (여기선 Authentication 이라고 제대로 표현되었다)
- 리소스에 대해 중개 프록시 서버에 의해 완료된 인증이 필요하다는 뜻이다.
- 프록시 서버는 접근 정책을 중앙 관리할 수 있기 때문에 단일 관리 포인트로도 많이 사용되기 때문에 이에 관련된 상태 코드를 따로 지원하는 것이다.
- 단, 프록시와 웹 서버 인증 헤더가 조금 다르다.
📍 407 상태코드 흐름 예시
408 Request Timeout
- Request Timeout ⇢ 요청이 너무 커 처리 시간이 초과되어 서버에서 요청을 처리하지 아니하고 연결을 닫음
- 만일 클라이언트의 요청을 완수하기에 시간이 너무 많이 걸리는 경우, 서버는 이 상태 코드로 응답하고 연결을 끊을 수 있다.
- 혹은 인터넷 연결이 매우 느리거나 끊어졌기 때문에 발생할 수도 있다.
- 서버의 타임 아웃 기준은 서버 설정마다 다르다.
- 408 응답은 서버가 연결을 닫기로 결정했음을 의미하므로, 응답할때
Connection: close헤더를 반드시 전송해야 한다. - 이 응답은 Chrome, Firefox 27+, IE9와 같은 일부 브라우저들이 웹서핑 속도를 높이기 위해 HTTP 사전 연결 메커니즘을 사용하기 때문에, 만일 네트워크가 불안정하면 종종 볼수 있는 응답이기도 하다.
📍 408 상태코드 흐름 예시
1. 클라이언트는 10K에 달하는 PDF 파일을 서버에 요청한다.
2. 서버는 요청 처리중 네트워크 연결이 간헐적인 문제로 인해 전체 전송 속도가 너무 느리다고 결론을 내리고 Connection 헤더를 통해 요청을 취소하고 연결을 닫음을 표시하고 응답하게 된다.
409 Conflict
- Conflict ⇢ 클라이언트의 요청이 서버의 상태와 충돌이 발생
- 요청 처리 중 비지니스 로직상 불가능하거나 모순이 생긴 경우 사용된다.
- 여타 4XX 상태 코드 처럼 요청에 있어 메소드 지원 유무나, 자원 유무, 인증 유무와 같은 확실한 오류 상황들을 제외한 로직 오류 상황에서 쓰인다.
- 사실 충돌(conflict)이라는 것은 추상적인 오류 현상이기 때문에, 여타 4XX 상태 코드에 속하지 않은 애매한 오류의 상황들을 처리하는데 이용된다고 보면 된다.
- 그래서 응답은 충돌에 대해 설명하는 구체적인 본문을 포함해야 한다.
📍 409 상태코드 흐름 예시
예를들어 회원 탈퇴를 하려고 하는데, 서비스 로직 특성상 회원 탈퇴를 하려면 지금까지 작성했던 게시글을 모두 삭제하여야 탈퇴가 가능하다라고 할때 그에 대한 오류를 403 Conflict 를 통해 알린다.
이밖에 병원 검진 예약을 진행하려는데, 클라이언트가 보낸 시간이 이미 예약이 잡힌 시간대여서 예약이 불가능하다고 가정할때도 409 응답을 보내주게 된다.
1. 클라이언트는 서버에게 회원 삭제 요청을 보낸다.
2. 서버는 회원 탈퇴를 위해선 비즈니스 로직상 우선 게시글들을 먼저 지워야 하기 때문에 그에 대한 구체적인 오류의 원인을 본문에 담은채 409 응답을 한다.
410 Gone
- Gone ⇢ 리소스가 영구히 삭제됨
- 404 Not Found와 비슷하나 410 응답은 요청한 컨텐츠가 서버에서 영구히 삭제되어 전달해 줄 주소가 존재하지 않을때 사용된다.
411 Length Required
- Length Required ⇢ 요청 메시지에
Content-Length헤더가 있을 것을 요구 - 서버에서 로직을 처리하는데 필요로 하는
Content-Length헤더 필드가 없어 서버가 요청을 거절할때 응답된다. - 클라이언트가 서버에 chunk 데이터를 보낼때, 인코딩을 받아들여주지 않을 경우에도 이용된다.
- 클라이언트는 요청 헤더에
Content-Length를 포함하고 재요청하면 된다.
412 Precondition Failed
- Precondition Failed ⇢ 클라이언트의 조건부 요청 실패
- 클라이언트가 캐시에 대한 조건부 요청을 했는데 실패했을 때 응답된다. (Etag나 수정일짜 불일치)
- 304 Not Modified 처럼 캐시 관련 요청에서 쓰이는 코드이다.
- 단, POST, PUT, DELETE 메소드 등 GET, HEAD 이외의 메소드에서만 요청했을때만 사용된다.
- 이 상태 코드를 따르면 '업데이트 손실' 문제를 피할 수 있다.
업데이트 손실은 여러 사람이 동일한 리소스를 쓰고 있고 한 명 이상이 오래된 버전으로 작업할 때, 리소스가 수정되지 않았는지 확인함으로써 중간에 수정된 데이터를 덮어쓰거나 수정하지 않도록 보장한다.
📍 412 상태코드 흐름 예시
예를들어 쇼핑몰 사이트에서 키보드가 1개만 남은 상태라고 가정해보자. 이때 두명의 소비자가 동시에 해당 키보드 구매 페이지에 접속하게 된다.
그리고 데스크탑으로 접속한 소비자가 먼저 구매 요청을 서버에게 보내었다. 그러면 1개 밖에 안남은 키보드는 품절이 되게 되고 쇼핑몰 서버는 해당 키보드 구매 페이지에 대해 품절이 되었다고 문서를 업데이트 한다.
하지만 아직 모바일로 접속한 소비자는 실제로는 품절됬음에도 불구하고 여전히 old 페이지를 바라보고 있기 때문에 여전히 구매하기 버튼을 누를 수 있게 된다. 여기서 모바일 소비자가 구매 버튼을 누르게 되면 바로 412 Precondition failed 를 응답하여 구매 로직이 처리되지 않도록 하는 것이다.
📉 412 상태 흐름
위의 과정을 시퀀스 다이어그램으로 표현하면 아래와 같이 된다.
- 먼저 모바일에서 쇼핑몰 사이트로 접속하고 문서를 캐싱한다.
- 그리고 서버는 모바일에게
Etag: x를 내려준다. - 웹에서도 쇼핑몰 사이트로 접속하고 문서를 캐싱한다.
- 문서 자체는 수정되지 않았으니 똑같이 서버는 웹에게
Etag: x를 내려준다. - 이때 웹이 먼저 구매 요청(PATCH)를 하게 된다.
- 서버는 If-Match 헤더값과 Etag 헤더값을 비교하여 둘이 x로 일치하니 문서를 최신상태로 업데이트(품절)하고 Etag를 y로 갱신하고 응답한다.
- 그후에 모바일이 구매요청을 한다.
- 하지만 모바일이 갖고있는 Etag는 x고 서버에 있는 문서의 Etag는 방금 웹에 의해서 y로 업데이트 되었으니, 불일치가 되고 서버는 구매 로직을 실행하지 않고 412 에러 응답을 보내게 된다.
🆚 304 와 412 상태 코드 차이
단순히 앞자리 숫자가 다르다를 물어보는 것이 아니다.
304 Not Modified 와 412 Precondition failed 는 웹브라우저의 캐시 관련 헤더와 연관된 상태 코드로서, 클라이언트의 리소스 수정 상태와 서버의 리소스 수정 상태가 다르면 응답하게 된다.
그럼 무슨 기준으로 어떤건 정상 코드이고 어떤건 오류 코드 인지 혼동이 올수 있는데 의외로 간단하다.
→ 304 응답은 GET 과 HEAD 메소드에만 동작한다.
→ 412 응답은 이를 제외한 POST, PUT, PATCH 등 메소드에만 동작한다.
따라서 위의 쇼핑몰 예제에서 412 응답이 반환된 이유는 PATCH 메소드를 통해 엑세스 하려고 하였기 때문이다.
413 Payload Too Large
- Payload Too Large ⇢ 요청 본문이 서버에서 정의한 한계보다 너무 커 처리할수 없음
- 413 Request Entity Too Large 로도 쓰여짐
- 서버가 처리할 수 있는 한계를 넘은 크기의 본문을 포함한 요청을 클라이언트가 보냈을 때 사용한다.
- 서버는 연결을 끊거나 혹은
Retry-After헤더 필드로 돌려보낼 것이다.
414 URI Too Long
- URI Too Long ⇢ 요청 URI이 너무 길어 처리할수 없음
- 413 Request URI Too Long 로도 쓰여짐
- 서버가 처리할 수 있는 한계를 넘은 길이의 요청 URI를 클라이언트가 보냈을때 응답된다.
415 Unsupported Media Type
- Unsupported Media Type ⇢ 요청한 미디어 포맷은 서버에서 지원하지 않음
- 서버가 이해하거나 지원하지 못하는 내용 유형의 본문을 클라이언트가 보낼때 응답된다.
416 Range Not Satisfiable
- Range Not Satisfiable ⇢
Range헤더 필드에 요청한 지정 범위를 만족시킬 수 없음 - 클라이언트가 리소스의 특정 범위를 요청했는데, 그 범위가 잘못되었거나 맞지 않을 때 응답된다.
417 Expectation Failed
- Expectation Failed ⇢
Expect요청 헤더 필드로 요청한 예상 반환 코드를 만족 시킬 수 없음 Expect요청 헤더와 연관있는 상태 코드 (성공하면 100, 실패하면 417)
📍 417 상태코드 흐름 예시
1. 클라이언트는 서버에게 10K 용량의 PDF 파일 전송을 요청한다. 이때 서버에게 가능한지 미리 물어보기 위해 Expect 헤더로 100 응답을 기대한다.
2. 하지만 서버는 10K에 달하는 PDF 파일을 보내줄수 없기 때문에 417으로 화답한다.
418 I’m a teapot
- I’m a teapot ⇢ 만우절 농담 상태 코드
- 이 오류는 1998년 만우절 농담이었던 하이퍼 텍스트 커피 포트 제어 규약(Hyper Text Coffee Pot Control Protocol)의 레퍼런스다.
420 Method Failure or Enhance your calm
- 클라이언트 오류를 나타내기 위해 서버에서 반환하는 비공식 클라이언트 오류
- Spring Framework에서 메서드가 실패했음을 나타내는 비공식 응답코드로도 쓰였음 (지금은 안쓰임)
421 Misdirected Request
- Misdirected Request ⇢ 잘못된 방향의 요청
- 의도하지 않은 요청을 받아 서버가 응답을 생성할 수 없음을 나타냄
422 Unprocessable Entity
- Unprocessable Entity ⇢ 서버에서 본문을 처리할수 없음
- 이 응답은 서버가 요청을 이해하고 요청 문법도 올바르지만 요청된 지시를 따를 수 없음을 나타냄
- 요청 데이터에 대해 validation 처리를 하면서 적합하지 않은 데이터를 받았을 때 반환
423 Locked
- Locked ⇢ 리소스는 접근하는 것이 잠겨있음
- 요청에 대한 대상 파일 또는 폴더가 잠겨 있을때 반환
- WebDAV에 사용되는 응답 코드
424 Failed Dependency
- 요청된 작업이 실패한 다른 작업에 의존하기 때문에 수행할 수 없음
- 즉, 이전 요청이 실패하였기 때문에 지금의 요청도 실패하였음을 의미
- WebDAV에 사용되는 응답 코드
426 Upgrade Required
- Upgrade Required ⇢ 프로토콜 업그레이드 권고
- 서버가 현재 프로토콜을 사용하여 요청을 수행 의사가 없음을 나타내기 위해 반환되는 응답 코드이다.
- 예를들어 서버는 HTTP/1.1 버전은 받지않고 HTTP/2 이상만 받는다고 할때, 클라이언트가 HTTP/1.1로 요청을 보내는 상황을 말할 수 있다.
- 서버는 응답할때
Upgrade헤더에 필요로 하는 프로토콜을 클라이언트에게 알려준다. - 프로토콜 관련 101 Switching Protocols 상태 코드와 관련이 있다.
📍 426 상태코드 흐름 예시
1. 클라이언트는 서버에게 HTTP/1.1로 요청을 보낸다.
2. 하지만 서버는 HTTP/1.1 요청 자체는 받지만, 이 프로토콜로 서버 로직을 처리하지 않도록 설계되어있기 때문에, Upgrade 헤더에 권고 프로토콜을 기재하고 426 응답을 반환한다.
3. 클라이언트는 HTTP/2로 통신하기 위해 현재 HTTP/1.1로 통신하고 있는 서버에게 프로토콜 업그레이드 요청을 한다.
4. 서버는 101 응답과 함께 HTTP/2 프로토콜로 전환을 시작한다.
5. 이제 클라이언트는 HTTP/2 로 서버와 통신하게 된다.
428 Precondition Required
- Precondition Required ⇢ 조건부 요청이 요구됨
- 서버가 클라이언트에게 요청을 조건부로 해야 함을 나타낸다.
- 일반적으로
If-Match와 같은 필수 전제 조건부 헤더가 누락됬을때 반환된다. - 만일 조건부 헤더가 서버 측 리소스 상태와 일치하지 않을 경우 응답은 412 Precondition Failed가 되게 된다.
📍 428 상태코드 흐름 예시
1. 클라이언트는 이전에 리소스를 요청해 복사본을 얻어 캐싱해놓았고, 그 이후 리소스 수정 요청을 보내는 상황이다. 이때 조건부 헤더를 넣지 않은채로 서버에게 보낸다.
2. 하지만 서버는 캐싱 관련 업데이트 손실이 발생하게 하지않기 위해 428 응답을 하게 된다.
3. 클라이언트는 조건부 헤더를 넣고 다시 보낸다.
429 Too Many Requests
- Too Many Requests ⇢ 클라이언트가 일정 시간 동안 너무 많은 요청을 보낸 경우
- 서비스가 클라이언트의 요청량을 제한하려는 경우 이용된다. (예를 들어 API 사용건수를 시간당 100개 로 제한)
- 혹은 디도스와 같은 비정상적인 방법으로 자원을 마구마구 요청하는 경우, 서버는 가용성을 위해 요청 임시 제한을 걸 수 있다.
Retry-After헤더를 이용하여 몇초 뒤에 재시도 할 것을 나타낸다.
📍 429 상태코드 흐름 예시
1. 클라이언트는 서버에게 요청을 마구마구 보낸다.
2. 서버는 클라이언트에게 Retry-After 헤더를 통해 1800초 뒤에 요청을 하라고 응답한다.
⚔️ 서버 공격에 대한 방어책
무차별 대입 공격에 대한 방어
무차별 대입 기밀성 공격(Brute-force)은 해커가 사용자의 비밀번호를 알아내기 위해, 패스워드값을 무작위로 넣고 로그인 요청을 무차별적으로 하는 것을 말한다. 서버는 요청에 제한을 두지않게되면 회원의 기밀성이 피해를 입을수 있으며 또한 서버 자체의 가용성에도 피해를 입을 수 있다. 따라서 서버는 이러한 공격에 대비해 인증관련 API 요청의 경우 n 시간 동안 n회만 요청 가능 하다는 룰을 정하고, 이것을 초과할 경우 429 응답을 하도록 설계한다.
디도스 공격에 대한 방어
도스(Dos) 공격 혹은, 디도스(D-Dos) 공격은 사용자의 정보 탈취가 목적이 아닌 무차별적인 요청으로 서버 자체에 과부하를 줘서 서비스를 먹통으로 만드는 것을 말한다. 이 공격을 단일이 하면 도스 공격이고 단체가 하면 디도스 공격이다.
따라서 서버는 n 시간 동안 n회만 요청 가능 하다는 룰을 정할 필요가 있는데, 단 429 상태 코드가 서버의 가용성에 대한 공격을 완벽히 막을수 있는 것은 아니다. 왜냐하면 서버 자체에 지속적인 요청 공격이 오는 것 자체는 막을수는 없기 때문이다. 429 응답을 해도 서버는 요청을 계속 받기 때문에, 따라서 추가적으로 네트워크 단에서 IP를 차단하는 조치가 필요하다.
하지만 그래도 서버는 429 응답을 통해 클라이언트 요청이 데이터베이스나 서버 내부 로직을 들쑤시고 다니는 것을 방어는 할수있기 때문에, 네트워크 엔지니어는 IP나 도메인에 대한 제한 처리를하고 백엔드 개발자는 429 응답을 통해 API 제한을 설정할 필요성이 있다.
431 Request Header Fields Too Large
- Request Header Fields Too Large ⇢ 헤더 필드가 너무 커서 요청을 처리하지 않음
- 총 요청 헤더 필드 수가 너무 많은 경우 또는 단일 헤더 필드가 너무 큰 경우 응답된다.
- 클라이언트는 요청 헤더 필드의 크기를 줄인 후 재요청 하면 된다.
451 Unavailable For Legal Reasons
- Unavailable For Legal Reasons ⇢ 법적인 이유로 비허용됨
- 클라이언트가 법적 이유로 사용할 수 없는 불법적인 리소스를 요청했음을 나타낸다. (정부에 의해 검열된 웹페이지 등)
# 참고자료
모든 개발자를 위한 HTTP 웹 기본 지식 - 김영한
HTTP 완벽가이드
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status
https://sanghaklee.tistory.com/61
https://http.dev/status
https://www.oreilly.com/library/view/http-the-definitive/1565925092/ch06s07.html
https://www.keycdn.com/
https://blogs.mulesoft.com/api-integration/patterns/advanced-api-patterns-with-raml/
이 글이 좋으셨다면 구독 & 좋아요
여러분의 구독과 좋아요는
저자에게 큰 힘이 됩니다.