- IP
- 패킷으로 정보를 주고 받는다
- 패킷에 출발지, 도착지 정보를 적어서 통신
- Ip 프로토콜의 한계
- 대상이 없어도 일단 발송되고 찾음
- 중간에 패킷이 사라지거나 패킷의 순서가 보장되지 않음 - 비신뢰성
- TCP가 하는 일
- IP 프로토콜을 기반으로
- 데이터를 전송하고 잘 받았다고 응답해줌
- 순서를 보장해줌
- UDP가 하는 일
- 하는 일이 없다
- IP 프로토콜에 포트개념이 추가된 약간 하얀 도화지 같은 개념이다
- IP를 커스텀하게 확장해서 사용할 수 있다
- 그럼 왜쓰나?
- TCP에서 연결 확인 등을 하기 때문에 느려지는데, 이런거 안하고 최적화 할때 사용함
- 그래서 연결 신뢰성보다는 성능이 중요한 비디오나 오디오에서 주로 사용함
- 근데 요즘 TCP쪽에서의 최적화도 진행하고 있긴함
- PORT
- 여러 프로그램이 통신을 사용하는 경우 패킷에 어느 프로그램에서 사용할지 정보도 적어줘야 한다
- IP가 아파트 동 주소 개념이면 포트는 호수개념
- 65535포트까지 사용할 수 있고, 1023번까지는 약속된 포트가 많아서 사용을 안하는 것이 좋다
- DNS
- URI
- URL과 URN을 포함하는 개념
- URL: 리소스가 있는 위치
- URN: 리소스의 별명
- 위치에 대한 설명은 없기 때문에 잘 사용되지는 않는다
- URL
- Scheme
- 스키마 부분에는 주로 프로토콜을 적는다
- http, https
- Userinfo
- 사용자 정보를 포함해서 데이터를 요청 할 때 사용
- SVN정도에 사용
- Host
- Port
- Path
- Query
- ?로 시작, &로 추가 가능
- ?keyA=valueA&keyB=valueB
- 쿼리 파라미터, 쿼리 스트링 등으로 불림
- Fragment
사용하여 표현
- 웹페이지 내의 위치 등을 표현할때 사용하고 잘 사용하지는 않음
- 서버로 전송되는 데이터가 아님
- URL을 사용하면 어떻게 되는가
- host를 dns로 던져서 실제 ip 주소 정보를 얻는다.
- 웹브라우저가 http 요청 메세지를 만든다
- 메세지에 패킷으로 감싸준다
- 서버로 던진다
- 서버는 패킷을 까서 메세지만 뽑아낸다
- 서버는 응답 메세지를 만들어서 반환한다
- HTTP
- 요즘에는 거의 모든 형태의 데이터를 http로 보낸다
- http1.1이 우리가 주로 사용하는 http이다
- 그 이상의 버전은 단순히 성능을 개선한 버전이다
- 클라이언트 서버구조
- Request response 구조
- 클라이언트는 서버에 요청을 보내고 응답 대기
- 무상태 프로토콜
- 서버가 이전 요청에 대한 정보를 갖고 있지 않다
- 필요할만한 정보는 클라이언트가 한번에 던져 준다
- 상태 프로토콜이 될 경우 항상 같은 서버가 결과를 주어야 하므로 하나의 서버로만 연결되어야 한다
- 무상태 프로토콜인 경우 서버가 달라져도 괜찮으므로 서버 확장이 쉽다. 즉, 수평 확장이 쉽다.
- 로그인 같은 경우에만 stateful 하게 사용한다
- 비연결성
- 연결을 유지하고서 통신하는게 아니라 필요할때만 보내고 받음
- 일반적으로 초 단위 이하의 빠른 속도로 응답
- 1시간동안 수천명이 서비스를 사용해도 동시에 처리하는 요청을 그렇게 많지 않아서 서버 자원을 세이브 할 수 있음
- 단점
- 연결 할 때마다 tcp/ip 연결을 해야 함
- 요즘엔 지속연결 기능을 넣어서 짧은 시간동안은 연결을 유지하도록 함
- http 메세지
- 공통구조
- Start line
- 요청메세지는 request line, 응답메세지는 status line이라고도 함
- Request line은 Method (space) path (space) http버전 형식으로 구성
- method는 get, post, put, delete 등으로 되어 있음
- path는 절대경로와 쿼리도 포함된다
- Status line은 http버전 (space) status code (space) reason phrase라고 하는 간단한 상태코드 설명 형식으로 구성
- Header
- Field name: value 형식
- Field name은 대소문자 구분을 하지 않는다
- value는 대소문자 구분을 한다
- http 전송에 필요한 모든 정보가 포함된다
- 표준 헤더라고 해서 일반적으로 자주 쓰는 헤더 종류도 굉장히 많고, 임의로 헤더를 만들어 보낼 수도 있다
- Empty line
- Message body
- 실제 전송할 데이터가 포함되며 바이트로 표현 할 수 있는 모든 데이터를 전송 가능하다
- 확장가능해서 좋다
- API URI
- 리소스 개념에는 행동이 들어가면 안된다
- 행위의 구분은 method로 한다
- Method
- Get: 리소스 조회
- Post: 요청 데이터를 보내서 처리, 등록에 주로 사용
- Put: 리소스를 대체하는 경우 사용, 해당 리소스가 없으면 만들어라
- Patch: 리소스 일부분의 데이터를 변경
- Delete: 리소스를 삭제
- Head: get과 동일하지만 메세지 부분을 제외하고 상태와 헤더만 반환해달라고 요청
- Options: 대상 리소스가 어떤 메소드가 사용가능한지 설명
- Connect: 서버에 대한 연결을 설정
- Trace: 리소스 경로를 따라서 메세지 루프백 테스트 수행
- Get
- 리소스를 조회할때 사용
- 전달하고 싶은 데이터는 query를 통해서 전달
- 최근에는 바디를 사용할 수도 있지만 일반적인 것은 아님
- Post
- 데이터를 주면서 처리를 바랄때 사용
- 새로 등록할때 주로 사용한다
- 회원가입, 글쓰기, 댓글달기, 신규주문생성, 기존자원에 데이터 추가
- 새로운 리소스 생성
- 요청 데이터 처리
- 뒤에 컨트롤 url를 넣어서 명령을 넣을 수 있다
- 다른 메서드를 처리하기 애매한 경우
- 사실상 모든걸 할 수 있다, 다만 get에는 캐싱 기능이 있기 때문에 조회할때는 get을 사용하는것이 좋음
- Put
- 리소스를 대체, 없으면 새로 생성
- 폴더에 같은 이름의 파일을 넣는다는 개념으로 생각하면 좋다
- Post와의 차이점은 put을 쓸때는 클라이언트가 이미 리소스를 식별하고 있다는 것이다
- 주의사항
- 리소스를 완전히 대체하므로 필드를 적게 넣어서 보내면 적게 넣어서 보낸 스키마로 덮어 써버린다
- Patch
- Put과 비슷하지만 기존 데이터의 일부분만 보내서 기존 데이터를 수정한다
- 필드를 적게 보내도 보낸 필드 부분만 수정한다
- 문제는 Patch를 인식하지 못하는 서버도 있다 이런 경우에는 post를 사용한다
- Delete
- HTTP 메서드의 속성
- 안전
- 호출해도 리소스를 변경하지 않는다는 개념
- 계속 호출해서 로그가 쌓이는 부분까지는 생각하지 않는다
- 멱등
- 한번 호출하든 백번 호출하든 같은 결과가 나온다
- 즉, 실수로 두번 보내더라도 결과는 같다
- Post메서드는 멱등이 아니다
- 다른곳에서 동시에 수정하는것까지 생각하지는 않는다
- 캐시가능
- 응답 결과를 캐시해놓아도 되는가?
- Get, Head, Post, Patch는 캐시해도 된다.
- 일반적인 경우는 Get, Head만 캐시
- 클라이언트와 서버의 통신 방법
- 쿼리 파라미터를 이용
- Get 방식에서 사용
- 주로 검색이나 정렬한 데이터를 얻을 때 사용
- 메시지 바디 사용
- Post, Put, Patch
- 회원가입, 상품주문, 리소스등록, 리소스변경
- 정적 데이터 조회
- Get 메소드로 리소스 바로 조회
- 이미지, 정적 텍스트 문서
- 일반적으로 쿼리 파라미터를 넣지 않아도 됨
- 동적 데이터 조회
- Get 메소드 사용하면서 쿼리 파라미터 사용
- 정렬, 필터 등 할 때 사용
- HTML 폼 데이터 전송
- Post 메소드로 저장
- Get도 지원을 하지만 검색창이나 필터창에만 사용
- 회원관리시스템
- 신규자원등록
- Post 사용
- Post /users
- 클라이언트는 등록된 리소스의 URI를 모른다
- 파일관리시스템
- 신규지원등록
- Put 사용
- Put /files/{fileName}
- 클라이언트가 리소스 URI를 알고 있어야 한다
- 즉, 클라이언트가 리소스 URI를 만들어준다
- HTML Form 사용
- Get, Post 만 사용 가능하다
- 회원 목록 Get /members
- 회원 등록 Post /members, Post /members/new
- 회원 조회 Get /members/{id}
- 회원 수정 Post /members/{id}
- 회원 삭제 Post /members/{id}/delete
- 즉, Get, Post만 지원하므로 제약이 있다.
- 동사로 된 리소스 경로를 사용하여 제약을 해결한다
- 참고하면 좋은 URI 설계 개념
- 문서
- 컬렉션
- 스토어
- 컨트롤러, 컨트롤 URI - 동사 형태로 사용한다
- Restfulapi.net
- 상태코드
- 1xx: 처리중
- 2xx: 정상처리
- 3xx: 완료하려면 추가 행동이 필요함, 리다이렉션
- 4xx: 클라이언트가 잘못함
- 5xx: 서버가 잘못함
- 1xx
- 2xx
- 200 - 성공
- 201 - 생성됨
- 202 - 접수는 되었지만 추후에 완료될 예정임
- 204 - 성공했지만 응답이 없음
- 일반적으로 200정도만 사용함
- 3xx
- 웹 브라우저는 300대 에러가 발생하면 응답으로 오는 location 헤더에 포함된 path로 리다이렉트하게 된다
- 영구리다이렉션, 일시리다이렉션, 특수리다이렉션
- 301, 308 - 리소스 URI가 영구적으로 이동
- 301
- 요청 메서드가 get으로 변하고 메세지 바디가 제거될 수 있음
- 308
- 302, 307, 303 - 일시적인 리다이렉션
- 302
- 요청 메서드가 get으로 변하고 메세지 바디가 제거 될 수 있음
- 307
- 303
- 일시적인 리다이렉션
- Post 로 주문 후에 새로고침 하는경우 get으로 리다이렉트 됨
- 304
- 캐시를 목적으로 사용한다
- 클라이언트에게 리소스가 수정되지 않았음을 알려준다
- 즉, 캐시로 리다이렉트 한다
- 4xx
- 오류의 원인이 클라이언트에 있다
- 똑같은 요청을 보내면 4xx에러가 발생해야 한다
- 400
- 클라이언트가 잘못된 요청을 한경우
- 요청 파라미터가 잘못된 경우
- 401
- 403
- 서버가 요청을 이해했지만 승인 거부
- 어드민만 접근 가능한 정보를 요청할 경우
- 404
- 요청한 리소스가 서버에 없음
- 403대신 사용하는 경우도 많음
- 5xx
- 500
- 503
- 사실상 500대 에러가 발생하면 절대 안됨
- 일반 헤더
- 헤더이름: 값
- HTTP 전송에 필요한 모든 부가 정보가 포함된다
- General: 메세지 전체에 적용되는 정보
- Request: 요청 정보
- Response: 응답 정보
- Entity: 엔티티 바디 정보 -> 표현이라는 개념으로 변경됨
- 표현
- 리소스의 전달할 형태를 서술
- Content-Type: 표현 데이터의 형식
- Content-Encoding: 표현 데이터의 압축 방식
- Content-Language: 표현 데이터의 자연 언어
- Content-Length: 표현 데이터의 길이
- 표현 헤더는 request, response 모두 사용함
- Content-Type
- Text/html; charset=utf-8
- Application/json
- Image/png
- Content-Encoding
- 데이터를 보내는 곳에서 압축 후 인코딩 헤더 추가
- 데이터를 받는 곳에서 인코딩 헤더의 정보로 압축해제
- Gzip, deflate, identity(압축을 안하겠다)
- Content-Language
- 표현 데이터의 자연 언어를 표현
- Ko, en, en-US
- Content-Length
- 표현 데이터의 길이
- 바이트 단위로 표시
- Transfer-Encoding을 사용하면 이 항목을 사용하면 안된다
- 협상
- 클라이언트가 선호하는 표현을 서버에게 요청하는 것이다
- 즉, 요청할때만 헤더에 사용한다
- Accept: 클라이언트가 선호하는 미디어 타입
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
- Accept-Language: 클라이언트가 선호하는 자연 언어
- 협상을 사용하지 않고 그냥 요청을 보내면 서버의 기본 언어로 결과를 받는다
- 서버가 지원하지 않는 언어를 요청하면 우선순위에 따라 결과를 보내준다
- 협상과 우선순위
- 클라이언트가 우선순위를 정해서 요청을 진행할 수도 있다
- Accept-Language: ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7
- 콤마로 구분, 값을 넣지 않으면 1로처리
- CSS처럼 구체적일수록 우선순위가 높다
- Text/*;q=0.3…
- 전송방식
- 단순전송
- Content-Length에 길이를 모두 적어주고 한번에 전송
- 압축전송
- Content-Encoding에 압축방법도 적어주고 전송함
- Content-Length에는 압축된 길이를 적음
- 분할전송
- Transfer-Encoding에 chuncked 라고 적어주고 전송함
- 서버가 보내주는 데이터를 분할해서 받을 수 있다
- Content-Length를 처음부터 예상 할 수 없으므로 적어주지 않는다
- 범위전송
- 클라이언트가 헤더 Range에 범위를 요청해서 보내면
- 서버가 헤더 Content-Range에 해당 범위를 적어서 보낸다
- 일반정보
- From: 일반적으로 사용되지않음, 검색 엔진에서 사용
- Referer: 이전 웹 페이지 주소, 어떤 사이트로 이동하는 경우 헤더에 이전 사이트 정보를 넣어서 요청한다, 오타지만 이미 사용한다, 유입 통계를 알 수 있다
- User-Agent: 웹브라우저나 클라이언트의 애플리케이션 정보, 로그를 통해 어떤 사이트에서 오류가 발생했는지 알 수 있다
- Server: 요청을 처리하는 origin 서버 정보, 중간에 있는 캐시서버등을 모두 제외하고 진짜 결과를 만들었다고 생각되는 서버 정보가 들어간다
- Date: 메시지가 발생한 날짜와 시간이 포함된다. 요청에는 포함되지 않고, 응답에만 포함
- 특별한정보
- Host: 요청에서 사용하면서 필수값이다, 서버는 호스트 값을 보고 내부 가상 호스팅을 진행한다
- Location: 300대 오류가 있으면 해당 주소로 리다이렉트한다
- Allow: 405에서 응답에 포함해야 한다, 그러나 일반적으로 잘 구현되지는 않음
- Retry-After: 유저 에이전트가 얼마나 이후에 다시 요청 할 수 있는지 적어준다
- 인증
- Authorization: <인증방법> <토큰>
- 쿠키
- Set-Cookie: 서버에서 클라이언트로 쿠키 전달
- Cookie: 클라이언트가 서버에서 받은 쿠키를 저장하고 요청시 전달
- HTTP는 무상태 프로토콜이라 서버는 이전 요청을 저장하지 않는다
- 그래서 계속 쿼리 등으로 정보를 보내주어야 한다.
- 하지만 이렇게 하면, 로그인만해도 요청에 사용자 정보가 모두 포함되도록 개발해야 하고,
- 브라우저를 완전히 종료하고 다시 열면 정보가 모두 사라지게 된다.
- 그래서 쿠키를 도입한다.
- 서버가 Set-Cookie: user=홍길동 형식으로 헤더에 정보를 넣어서 보낸다.
- 브라우저는 쿠키 저장소에 user=홍길동 형식으로 저장해 놓는다.
- 브라우저가 요청을 보내게 되면 Cookie: user=홍길동 형식으로 항상 보내게 된다.
- 사용자 로그인 세션 관리 할 때 자주 사용
- 광고 정보 트래킹 할 때 사용
- 트래픽을 추가유발하므로 최소한의 정보만 사용하는것이 좋다
- 서버에 전송하지 않고, 웹 브라우저 내부에 데이터를 저장하고 싶으면 웹 스토리지에 넣어놓는게 좋다
- 쿠키든 웹 스토리지든 보안에 민감한 데이터는 저장하면 안된다
- 쿠키 생명주기 관리
- Set-Cookie: expires=Sat, 26-Dec…
- Set-Cookie: max-age=3600(0이나 음수를 지정하면 쿠키를 삭제할 수 있다.)
- 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료시까지 유지
- 영속 쿠키: 만료 날짜를 입력하면 해당 날짜까지만 유지
- 쿠키 도메인
- Domain=example.org
- 명시한 문서 기준으로 도메인, 서브도메인 모두 포함된다.
- 도메인을 지정하지 않으면 현재 일치하는 도메인에서만 쿠키에 접근 할 수 있다.
- 쿠키 경로
- Path=/home
- 이 경로를 포함한 하위 경로만 페이지만 쿠키에 접근하다
- 일반적으로 루트로 둔다
- 쿠키 보안
- Secure
- 일반적으로 쿠키는 http, https를 구분하지 않고 전송하지만, Secure를 적용하면 https인 경우에만 전송한다
- httpOnly
- Xss 공격방지
- 자바스크립트에서 접근 불가
- http 전송에만 사용
- SameSite
- XSRF 공격방지
- 요청 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키 전송
- 캐시 기본 동작
- 캐시가 없으면 데이터가 변경되지 않아도 계속 네트워크를 통해서 데이터를 다운받는다
- Cache-control: max-age=60
- 60초동안은 다시 요청하더라도 요청을 보내지않고 캐시에서 얻음
- 시간이 초과되면 다시 요청을 보냄
- Last-Modified: 데이터가 마지막에 수정된 시간
- If-modified-since: 요청할때 클라이언트 부분에서 받았던 수정시간을 적어준다.
- 캐시 만료되더라도 서버에서 데이터를 변경하지 않았을 경우, 바디를 보내지 않고
- 304 Not Modified를 전송한다.
- 다만, 1초 미만 단위로 캐시 조정이 불가능하고
- 실제 컨텐츠가 같은지까지는 호가인하지 않는다
- 그래서 캐시용 데이터에 임의의 고유한 버전 이름을 달아둔다(ETag)
- 캐시 제어 헤더
- Cache-Control:
- max-age: 유효시간 초단위
- No-cache: 데이터는 캐시해도 되지만 원서버에 검증하고 사용
- No-store: 데이터가 민감하므로 절대 저장하지마라
- Expires: 정확한 날짜로 만료일 지정
- 다만, 캐시 컨트롤이 더 정확하므로 max-age가 지정되면 이 헤더는 무시된다.
- 프록시 캐시
- Cache-Control: public - 응답이 퍼블릭 캐시에 저장되어도 되는경우
- Cache-Control: private - 응답이 해당 사용자를 위한 개인적인 것임
- Cache-Control: s-maxage - 프록시 캐시에만 적용되는 max-age
- Age: 60 - 오리진 서버에서 응답 후 프록시 캐시 내에 머문 시간