[HTTP]웹개발을 위한 기본지식
Updated:
HTTP
이 게시글은 웹개발에 앞서 필요한 지식인 HTTP에 관해 다룬다
RESTful API
/read-member-list // 회원목록 조회
/read-member-by-id // 회원 조회
/create-member // 회원 등록
/update-member // 회원 수정
/delete-member // 회원 삭제
웹개발 시에 URI설계를 어떻게 할지는 중요한 문제이다. 명확하게 정해진 규칙이 없다면 위와 같이 CRUD기능을 수행하는 각 URI가 뒤죽박죽 되기 때문이다. 그래서 등장한 것이 RESTful한 API 설계방식이다. 여기서 중요한 것이 리소스와 행위를 분리하는 것이다. 예를 들어 여기서 리소스는 회원을 의미하고, 행위는 CRUD의 동작을 의미한다
/members // 회원목록 조회
/members/{id} // 회원 조회
/members // 회원 등록
/members/{id} // 회원 수정
/members/{id} // 회원 삭제
문제는 RESTful API설계를 하게 되면 위와 같이 동일한 URI들이 존재하게 된다는 점이다. 이를 구분해주기 위해 HTTP method를 이용한다
RESTful API에서 대표적인 HTTP method는 아래와 같은 의미를 가진다. 아래는 대표적인 method이고 이외에도 다양한 method가 존재한다
- GET 리소스 조회
- POST 요청 data 처리
- PUT 리소스 수정
- PATCH 리소스 부분변경
- DELETE 리소스 삭제
1. GET
- 리소스 조회
- client가 GET방식으로 요청을 보내면 server는 해당되는 data를 body에 담아 응답하는 방식
- server에 전달하고 싶은 data가 있다면 쿼리 파라미터를 이용
- POST방식처럼 msg body를 통해 data를 전달할 수 있지만 지원하지 않는 경우가 대다수
- 응답결과 리소스를 캐시하여 사용가능
2. POST
- 요청 data 처리
- client는 msg의 body를 통해서 server로 요청 data를 전달
- server는 msg의 body를 통해서 들어온 data를 처리하는 모든 기능을 수행
- 주로 새로운 리소스를 등록하거나 프로세스의 상태를 변경해야할때 사용
- 어떤 method를 써야할지 애매할 경우에 사용
3. PUT
- 리소스가 존재하면 완전히 대체(보내준 data로 모두 덮어씀)하고 없을 경우 새로 생성
- POST와 달리
/members/{id}처럼 리소스 위치를 알고 URI를 지정
4. PATCH
- 리소스 부분변경
- POST와 다르게 완전히 대체하는 것이 아니므로 특정 필드의 값만 수정가능
5. DELETE
- 리소스 삭제
Data 전송방식
1. HTML Form data전송
- POST 전송
- Content-Type은 application/x-www-form-urlencoded로 설정
- form의 내용을 msg body를 통해서 전송(‘key=value’형식)
- 전송되는 data를 url encoding 처리
- Content-Type이 Multipart인 경우
- HTML form의 여러 필드값들을 구분하여 전송
2. API data 전송(AJAX 통신)
- client에서 server로 바로 data를 전송하는 경우
- Content-Type은 application/json으로 설정하는 것이 표준
POST, PUT을 이용한 신규 자원 등록
1. POST
- client가 URL형태로만 요청해도 server에서 명확한 리소스에 해당하는 URI를 응답
- 예를 들어,
/members의 형태로만 요청해도 server가/members/{id}의 형태로 반환해줌 - 여기서
/members를 Collection이라고 부름
2. PUT
- client가 직접 리소스의 URI를 지정하여 server에 요청 즉, client가 리소스의 URI를 알고 있어야함
- 예를 들어, client가
/files/{filename}의 형태로 직접 server에 요청해야함 - 여기서
/files를 Store라고 부름
=> 대부분 POST 기반의 신규자원 등록을 사용한다!!!
HTML Form 사용시
- HTML Form은 GET과 POST 방식만 지원
- PUT, PATCH, DELETE 방식을 사용못한다는 제약이 있어서 컨트롤 URI라는 것을 사용
- POST 방식에서
/new,/edit,/delete등 동사를 등 동사를 붙이는 것이 컨트롤 URI - 실제로 현업에서 HTTP Method만으로 해결하기 어려울때 자주 사용
- POST 방식에서
HTTP 상태코드
client의 요청에 대한 처리상태를 server가 응답으로 알려주는 기능으로 아래 5가지의 상태로 구분된다
- 1xx: 요청이 수신되어 처리중(거의 사용X)
- 2xx: 정상적인 요청 처리
- 3xx: 요청을 완료하기 위해 추가적인 행동 필요
- 4xx: client 오류로 server가 요청 수행불가
- 5xx: server 오류
상세코드가 정확히 무슨 뜻을 의미하는지 모를 경우 첫번째 자리 숫자만 확인하여 위 5가지로 나눠 대략적인 의미를 파악할 수 있다. 아래에서는 각 상태별로 상세코드를 알아보고자 한다
2XX
-
정상적인 요청을 처리하는 경우
-
종류
- 200 OK
- 요청 성공한 경우
- 201 Created
- 요청이 성공하여 새로운 리소스가 생성된 경우
- 생성된 리소스는 응답 Header의 Location 필드로 확인가능
- 202 Accepted
- 요청이 접수되었지만 처리가 완료되지 않은 경우
- 204 No Content
- server가 요청을 성공적으로 수행했지만 응답으로 보낼 data가 없는 경우
- 예를 들어, 웹문서 편집기에서 save를 누른 경우가 이에 해당됨
- 200 OK
3XX
해당 상태코드를 살펴보기 이전에 Redirection에 대해 알아볼 필요가 있다
Eg) Redirection 동작 예시
- client가
/old-url로 server에 요청 - server가 변경된 새 URI인
/new-url을 Header의 Location필드에 담아 응답 - 웹브라우저가 해당 URI로 리다이렉트한 후 server에
/new-url로 요청 - server가 해당 요청에 대한 응답
Redirection
- 정의: 3XX 응답의 결과에 Header의 Location 필드가 있다면 명시된 위치로 웹브라우저가 자동으로 이동하는 기능
- 종류
- 영구 Redirection
- 특정 리소스의 URI가 영구적으로 변경되는 경우
- 일시 Redirection
- 특정 리소스의 URI가 일시적으로 변경되는 경우
- 실무에서 주로 사용하는 방식
- 특수 Redirection
- 영구 Redirection
영구 Redirection
- 301 Moved Permanently
- 리다이렉트 시에 요청 method가 GET으로 바뀌고 요청했던 body본문이 제거될 수 있음
- URI 변경 시에 내부적으로 전달해야 되는 data가 대부분 바뀌기 때문에 사실 실무에서 308보다는 301을 주로 사용
- 308 Permanent Redirect
- 리다이렉트 시에 요청 method가 처음 요청과 동일하게 적용되고 요청했던 body본문 역시 유지됨
일시 Redirection
- 302 Found
- 리다이렉트 시에 요청 method가 GET으로 바뀌고 요청했던 body본문이 제거될 수 있음
- 307 Temporary Redirect
- 리다이렉트 시에 요청 method와 body본문 유지
- 303 See Other
- 302와 기능이 유사
- 리다이렉트 시에 요청 method를 GET으로 변경
PostRedirectionGet(PRG)
- 예를 들어 POST로 임의의 주문 후에 웹브라우저를 새로고침할 경우 중복주문 처리가 될 수 있음
- 이런 경우를 방지하기 위해 server에서도 방지처리를 수행해야하지만 client측에서도 PRG로 대비할 필요가 있음
- POST로 임의 주문 후에 리다이렉션을 GET Method로 변경해주어 웹브라우저에서 새로고침을 해도 아무런 문제가 없도록 처리
특수 Redirection
- 304 Not Modified
- cache를 목적으로 사용
- client에게 임의의 리소스가 수정되지 않았음을 알려주어 local에 저장된 cache를 재사용해도 된다고 알려주는 역할
- local cache를 사용해야 하므로 응답에 msg body를 포함하면 안됨
4XX
- 오류가 발생한 원인이 client측에 있는 경우
- 5XX 오류와 달리 client가 동일한 요청을 재시도해도 똑같이 잘못된 요청이기 때문에 실패함
- 종류
- 400 Bad Request
- 요청 구문, msg 등의 오류
- 요청 파라미터가 잘못되었거나 API 스펙이 맞지 않는 경우
- 401 Unauthorized
- 인증(Authentication)되지 않은 경우
Cf) 인증 vs 인가
인증(Authentication): 본인확인(로그인)
인가(Authorization): 로그인 후에 특정 리소스에 접근할 수 있는 권한(인증이 우선시되야함) - 응답에 Header의 WWW-Authenticate 필드와 함께 인증방법을 제시함
- 인증(Authentication)되지 않은 경우
- 403 Forbidden
- 인증(Authentication)은 되었지만 인가(Authorization)되지 않은 경우
- 예를 들어 로그인은 했지만 접근할 수 없는 권한을 가지고 해당 리소스에 접근하는 경우
- 404 Not Found
- 요청한 리소스가 server에 없는 경우
- 400 Bad Request
5XX
- server 문제로 인해 오류가 발생한 경우
- 4XX 오류와 다르게 재시도하면 성공할 수도 있음
- 종류
- 500 Internal Server Error
- server 내부 문제로 오류 발생한 경우
- 503 Service Unavailable
- server가 일시적인 과부하되거나 예정된 작업으로 인해 잠시 요청을 처리할 수 없는 경우
- 500 Internal Server Error
HTTP Header - 일반
HTTP 전송에 필요한 모든 부가정보를 담고 있는 일반적인 HTTP Header에 대해 알아본다
- msg body를 통해 표현 데이터를 전달 cf) msg body = payload
- 표현 데이터는 요청이나 응답으로 전달할 실제 data를 뜻하고, 표현 헤더는 표현 데이터를 해석하기 위한 정보를 제공함
표현
- Content-Type
- 표현 데이터의 형식, 문자 인코딩을 명시
- 종류
- text/html: HTML타입
- application/json: JSON타입
- application/xml: XML타입
- Content-Encoding
- 표현 데이터를 어떤 방식으로 압축하고 압축 해제할지를 명시
- data를 전송하는 측에서 특정 방식으로 압축 후 Header에 명시해놓으면 전달받는 측에서 해당 방식으로 압축 해제
- Content-Language
- 표현 데이터가 어떤 국가의 언어인지를 명시
- Content-Length
- 표현 데이터의 길이를 명시
- 바이트 단위
협상
- client가 선호하는 표현을 server에 요청하는 것을 의미함
- 종류 -> client에서 server에 요청 시에 사용하는 HTTP Header
- Accept: client가 선호하는 미디어 타입
- 여러 속성을 적어놓을 경우에 구체적인 것이 더 우선순위가 높음
- Accept-Charset: client가 선호하는 문자 인코딩
- Accept-Encoding: client가 선호하는 압축 인코딩
- Accept-Language: client가 선호하는 자연 언어
Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7와 같이 각 언어별 우선순위를 정해 해당 사이트에서 1순위 언어를 지원하지 않을 경우에 다음 우선순위의 언어로 응답받도록 설정할 수 있음- 위의 3가지 Accept필드들도 모두
q=(우선순위)형식으로 우선순위를 지정해줄 수 있음
- Accept: client가 선호하는 미디어 타입
전송 방식
- client의 요청에 대해 server가 응답으로 msg body를 전송하는 방식
- 종류
- 단순 전송
- 한번에 요청하고 한번에 응답받는 방식
- 해당 msg body에 대한
Content-Length를 HTTP Header로 응답해줌
- 압축 전송
- msg body를 압축하여 전송하는 방식
Content-Length뿐만 아니라Content-Encoding도 함께 담아 HTTP Header로 응답해줌
- 분할 전송
- chunk단위로 msg body를 쪼개 도착한 chunk별로 우선적으로 확인가능하도록 하는 방식
Transfer-Encoding을 HTTP Header로 응답해줌Content-Length는 보낼 수 없음
- 범위 전송
- client가 응답받을 범위를 지정하여 요청함으로써 오류 발생 시에도 특점 범위만을 응답받을 수 있도록 한 방식
- client는
RangeHTTP Header를 통해 범위를 요청하고, server는Content-Range를 통해 client에게 보내는 msg body의 범위를 명시함
- client는
- client가 응답받을 범위를 지정하여 요청함으로써 오류 발생 시에도 특점 범위만을 응답받을 수 있도록 한 방식
- 단순 전송
일반 정보
- Referer
- 현재 페이지 이전 요청에 해당하는 웹페이지 주소를 가리킴
- 임의 페이지의 유입경로를 분석하기 위해 주로 사용
- User-Agent
- client의 웹브라우저 정보를 포함한 application 정보
- 어떤 종류의 브라우저에서 장애가 발생하는지 분석하기 위해 주로 사용
- Server
- 요청을 처리하는 Origin Server의 소프트웨어 정보
- cf) Origin Server: client의 요청을 처리하는 중간 Proxy Server들이 아닌 최종경로에 위치하는 server
- 요청을 처리하는 Origin Server의 소프트웨어 정보
- Date
- msg가 발생한 날짜와 시간 정보
- 응답에서만 사용함
추가 특별한 정보
- Host
- 요청한 호스트 정보(도메인)을 나타내며 필수값
- 하나의 IP주소에 여러 도메인이 적용되어있을 경우를 위함
- Location
- 3XX HTTP 상태코드에서 응답의 결과 HTTP Header에 Location값이 있다면 명시된 위치로 자동으로 redirect시켜줌
- Allow
- 특정 HTTP Method만을 제공한다고 명시
- Retry-After
- 503 HTTP 상태코드에서 언제까지 서비스가 이용불가능한지 명시
인증
- Authorization
- client의 인증정보를 server에 전달함
- WWW-Authenticate
- 401 HTTP 상태코드에서 리소스 접근시 필요한 인증방법을 명시하기 위해 응답으로 보내줌
쿠키
- 기본적으로 server는 stateless를 지향하기 때문에 각 client와 요청과 응답을 주고받은후 연결을 끊어버려서 이전 요청을 기억하지 못함 -> 이를 해결하기 위해 쿠키라는 개념을 도입함
- client가 로그인 요청을 하면 server는 HTTP Header의
Set-Cookie필드에 해당 유저 정보를 담아서 client에 전달하고 웹브라우저는 이를 쿠키 저장소에 저장한다. 웹브라우저는 해당 server에 요청 시에 무조건 쿠키 저장소를 확인하고 쿠키정보가 존재한다면Cookie필드 값을 포함하여 보냄 - 사용자 로그인 세션 관리 및 광고정보 트래킹 시에 주로 사용
- 쿠키는 default로 항상 server로 전송이 되는데, 전송하지 않고 웹브라우저 내부에 데이터를 저장하고 싶다면 웹 스토리지를 이용하면됨
- 생명주기
Set-Cookie의expires값이나max-age값을 통해 쿠키 만료설정이 가능함- 만료날짜를 생략하여 브라우저 종료시까지만 유지하는 세션 쿠키와 만료 날짜를 명시하여 해당 시점까지만 유지하는 영속쿠키로 구분됨
- 도메인
Set-Cookie의domain값을 통해 특정 도메인에서만 쿠키를 전송하도록 설정가능domain=sample.org처럼 domain값을 설정해주면 sample.org 사이트 뿐만 아니라 sample.org를 포함하는 사이트에서도 쿠키를 사용가능함
- 경로
Set-Cookie의path값을 통해서 해당 경로의 페이지만 쿠키접근이 가능하도록 설정가능
- 보안
Set-Cookie의Secure값을 통해서 https인 경우에만 쿠키 전송하도록 설정가능Set-Cookie의HttpOnly값을 통해서 XSS 공격방지를 위해 사용하고 JS에서 접근불가능하도록함Set-Cookie의SameSite값을 통해서 요청 도메인과 쿠키에 설정된 도메인이 같을 경우에만 쿠키 정송하도록 설정가능
HTTP Header - 캐시와 조건부 요청
캐시의 기본동작과 조건부 요청 그리고 이를 다루는 HTTP Header에 대해 알아본다
캐시 기본 동작
- 캐시가 없을 경우 원하는 데이터를 상대적으로 느리고 비싼 인터넷 네트워크를 통해서 계속 받을 수 밖에 없음
- 동작 과정
- 캐시를 사용할 경우 server는 HTTP Header에
Cache-Control값을 적어 응답해줌- 여기서
Cache-Control값은 캐시가 유효한 시간을 의미함
- 여기서
- 웹브라우저는 캐시를 받아 브라우저 캐시 저장소에 응답결과를 유효시간 동안 저장함
- 5번 과정에서 기존 데이터 변경여부를 확인하기 위해 HTTP Header의
Last-Modified필드값을 함께 저장함
- 5번 과정에서 기존 데이터 변경여부를 확인하기 위해 HTTP Header의
- 이후부터 유효시간 동안 server에 접근할 필요없이 cache에 접근하여 요청을 처리할 수 있음
- 요청시간이 경과한 후에는 기존 데이터 변경여부에 따라 수행동작의 차이가 있음
- local cache와 server의 데이터가 일치함을 증명하기 위해서 검증 헤더를 사용함
- 여기서
Last-Modified를 검증 헤더라고 부름
- 요청시간 경과후 server에
If-Modified-Since값으로 2번과정에서 저장한Last-Modified값을 담아 요청함- 여기서
If-Modified-Since를 조건부 요청이라고 부름
- 여기서
- 수정일 차이가 없다면 304 Not Modified로 HTTP Header만 보내주고 변경사항이 있다면 200 OK로 HTTP Body까지 응답결과로 보내줘야함
- 변경사항이 없다면 큰 용량을 차지하는 HTTP Body를 제외하고 응답함
- 캐시를 사용할 경우 server는 HTTP Header에
검증 헤더와 조건부 요청
- 기본적으로 위에서 설명한
Last-Modified와If-Modified-Since를 검증헤더와 조건부 요청으로 사용할 수 있음- 위 방식의 단점
- 1초 미만 단위로 캐시조정이 불가능
- 데이터를 변경했지만 다시 원래 데이터로 바꾸었을 경우 갱신일은 바뀌지만 데이터는 그대로일 수 있음
- 위 방식의 단점
- 이 문제를 해결하기 위해
ETag와If-None-Match를 사용함ETag는 해시값을 통해 데이터가 변경여부를 확인하여 변경되었을 경우 이름을 바꿈- 해시값 특성상 변경후 다시 원래 데이터로 돌아올 경우 동일한 해시값이 나옴
ETag를 HTTP Header의If-None-Match필드값으로 보내 server와 동일하면 유지하고, 다를경우 다시 응답받음- 위 동작과정과 다르게 처음 server에서
Last-Modified값이 아닌ETag값을Cache-Control과 함께 HTTP Header로 client에게 전달하여 local cache에서 이를 저장함
캐시와 조건부 요청 헤더
캐시 제어 헤더
Cache-Control- 캐시의 유효기간 등 캐시를 제어하기 위한 헤더
- 캐시 지시어
max-age: 캐시의 유효시간을 설정no-cache: 항상 Origin Server에 접근하여 데이터 검증 후 사용하도록 설정- Origin Server와 Local Cache의 데이터가 일치한다면 캐시의 데이터를 사용해도됨
no-store: 데이터에 민감한 정보가 있어 메모리에서 사용후 빠르게 삭제하도록 설정
검증 헤더
ETagLast-Modified
조건부 요청 헤더
If-Modified-SinceIf-None-Match
프록시 캐시
- client가 임의의 데이터에 접근하기 위해서 매번 Origin Server에 접근하면 시간이 오래걸리기 때문에 Origin Server와 Client 사이에 Proxy Cache Server를 도입함
- 여기서 client의 local에 존재하는 캐시를 private 캐시라고 부르고, 외부의 Proxy Cache Server에 존재하는 캐시를 public 캐시라고 부름
- 기타 캐시 지시어
public: 응답이 public 캐시에 저장해도 되도록 설정private: 응답이 private 캐시에만 저장되도록 설정(default)s-maxage: Proxy Cache Server에만 적용되는 max-age 설정
캐시 무효화
- 캐시 관련 설정을 적어주지 않는다고 해서 캐시를 사용하지 않는 것이 아님에 주의!!!
- 캐시를 확실히 무효화하기 위해선
Cache-Control: no-cache, no-store, must-revalidate를 HTTP Header에 적어주어야함- HTTP 1.0 버전까지 대응하기 위해서
Pragma: no-cache까지 적어주면됨 must-revalidate는 캐시 만료 후에 최초로 접근 시에는 Origin Server에 검증하도록 하는 설정no-cache설정과 거의 유사하지만no-cache는 네트워크 오류로 Origin Server 접근 실패 시에 Proxy Cache Server의 데이터를 전달해주는 반면,must-revalidate는 Origin Server 접근 실패 시에 504 Gateway Timeout 오류메시지를 전달함- 예를 들어, 은행잔고확인 시에 네트워크 오류로 Origin Server 접근 실패할 경우 Proxy Cache Server의 과거 데이터를 가져오는 것보다 오류 메시지를 전달해주는 것이 적절함
- HTTP 1.0 버전까지 대응하기 위해서
Leave a comment