티스토리 뷰

HTTP는 stateless하다

HTTP는 웹 서버와 웹 브라우저가 데이터를 주고받기 위한 약속이다. HTTP는 상태를 가지지 않는다. 이 말은 웹에서 데이터를 주고받을 때 상태를 가지지 않는다는 것이다. 클라이언트가 서버에 어떤 요청을 하면 서버는 그 요청을 곧이곧대로 듣고 적절한 응답을 해주지만, 처리 후에 그 일을 기억하고 있지 않다. 항상 아메리카노를 주문하는 카페에 가서 '늘 마시는 것으로 주세요'라고 해도 처리를 못하는 것이다. 카페 입장에선 항상 처음 보는 사람이고 어떤 메뉴를 주문했는지 정보를 알고 있지 않다.

단골 손님인데 매번 처음 보는 사람으로 인식한다면 손님 입장에서는 항상 장황하게 주문을 해야하고 불편할 것이다. 그래서 카페에서 어떤 특별한 영수증을 준다. 이 영수증을 가지고 오면 우리 단골 손님이라고, 자주 시키는 메뉴가 아메리카노라고 참고하겠다는 것이다. 만약에 이제 아메리카노를 잘 안시키고 라떼를 자주 시키면 카페에서 이 영수증에 라떼를 자주 시킨다고 수정을 할 것이다.

이러한 영수증처럼 인터넷에서도 '쿠키'라는 개념을 만들어 서버가 클라이언트에게 쿠키를 준다. 클라이언트는 이 쿠키를 받은 이후부터 어떤 요청을 할 때마다 자동으로 쿠키를 함께 보낸다(브라우저가 해준다). 예를 들어서 클라이언트가 어떤 웹사이트를 여러 번 방문할 때, 쿠키가 없다면 서버 입장에서는 항상 처음 보는 사람이다. 그런데 첫 방문에 서버가 쿠키를 심어놓았기 때문에 다음 방문부터는 브라우저가 서버에게 자동으로 쿠키를 보내고, 서버는 쿠키를 보고 그 사람을 알아본다. 로그인 시 아이디가 자동으로 입력되어 있는 기능도 서버가 '쿠키를 보니 지난번에 아이디를 저장해달라고 하셨네요? 그대로 입력해드리겠습니다' 라고 하는 것이기 때문에 쿠키를 통해서 가능한 일인 것이다. 예시

상태를 가지고 있지 않는, 정보를 기억하고 있지 않는 HTTP통신의 이러한 문제점을 보완하기 위해 지속할 필요가 있는 데이터를 쿠키에 저장시켜 놓고 사용한다.

 

쿠키(Cookie)

쿠키는 서버가 클라이언트에 지속성있는 데이터를 저장하는 방법이다. 서버가 클라이언트(브라우저)에 쿠키를 심는다. 쿠키에는 저장하고자 하는 어떤 데이터들이 담겨있다. 그리고 이 쿠키를 가진 클라이언트가 서버에 어떤 요청을 할 때마다 브라우저가 자동으로 HTTP헤더에 쿠키를 포함시켜서 같이 요청을 보낸다. 

쿠키는 서버에서 심어주고 정보도 보내주지만 클라이언트에서 확인하고 삭제할 수도 있다. 애플리케이션 탭의 쿠키에서 해당 사이트의 쿠키를 확인할 수 있다. 나의 티스토리 블로그도 이렇게 키-값 형태로 많은 쿠키들이 저장되어 있다.

 

쿠키를 받을 수 있도록 서버에서 옵션 설정

// cookie options
{
    domain: 'localhost',
    path: '/',
    secure: true,
    httpOnly: true,
    sameSite: 'strict',
    expires: new Date(Date.now() + 1000 * 60 * 60 * 24 * 7),
}

 

서버가 쿠키를 생성해서 클라이언트에게 보내주었지만, 언제나 누구나 사용할 수 있는 것은 아니다. 쿠키를 생성할 때 옵션을 설정해주어 쿠키를 돌려받을 수 있는 조건을 특정해주어야 한다. 쿠키를 확인할 수 있는 자격을 설정하는 것이다. 그렇지 않으면 누구나 어떤 쿠키든 다 확인하고 사용할 수 있어 위험하다. 네이버에서 나에 대한 어떤 정보를 저장해서 쿠키를 주었는데 다른 사이트, 다른 사람이 무분별하게 볼 수 있는 것은 옳지 못하다.

MaxAge 또는 expires

쿠키는 세션(session) 쿠키와 영속(permanent) 쿠키 두 종류가 있다.
옵션 중 만료 기간을 설정해주지 않으면 세션, 만료 기간을 설정해주면 영속 쿠키이다. 만료 기간은 MaxAge(만료 기간, 초 단위)나 expires(만료 시점, 특정 시간)로 설정해준다. (둘 다 설정해주면 MaxAge가 우선시된다)
세션 쿠키는 브라우저의 탭이나 창을 닫으면 만료되어 다음에 접속해서 요청을 할 때 더이상 서버에 돌려보내지 않는다.
영속 쿠키는 만료 기간을 설정해준만큼 브라우저를 종료하고 다시 접속해도 살아 있다.

Domain

domain이 설정되어 있다면 클라이언트에서 쿠키를 전송할 때, domain이 일치하는 서버로만 보낼 수 있다.
naver.com에서 domain을 naver.com으로 설정해서 생성해준 쿠키를 google.com으로 보낼 수 없다.

Path

domain처럼 path도 설정해준다. 서버가 라우팅할 때 사용하는 경로이다. 기본값은 '/'이다. 만약 '/user'로 설정되어있다면 '/user/chats'로 요청할 때에도 쿠키를 전송할 수 있다.

Secure

true이면 프로토콜이 HTTPS인 경우에만 쿠키를 전송할 수 있다. 
(예외 Secure이 true여도 도메인이 localhost인 경우, 개발할 때 많이 쓰이기 때문에 편의상 쿠키를 전송할 수 있다.)

HttpOnly

쿠키는 자바스크립트로도 접근 가능하다. document.cookie를 하면 된다.

HttpOnly: false일 때 document.cookie로 확인 가능하다

쿠키는 위에서 본 것처럼 브라우저의 개발자 도구를 통해 손쉽게 확인할 수 있고 변경할 수도 있다. 쿠키를 내 마음대로 수정해서 서버에 요청하는 것도 가능한 일이다. 제 3자가 할 수도 있을 것이다.  HttpOnly를 true로 설정해주면 막을 수 있다.

SameSite

Lax, Strict, None 중에서 설정해준다. 

Lax(느슨한 옵션): 다른 사이트라면 GET 요청에 대해서만 쿠키를 전송할 수 있다.
Strict(엄격한 옵션): 같은 사이트여야지만 쿠키를 전송할 수 있다.
None(모두 허용): 다른 사이트여도 항상 쿠키를 전송할 수 있다.(Secure옵션이 true이어야 한다.)

여기서 사이트의 기준이 있다. eTLD+1(effective Top Level Domain plus One), eTLD+1이 다른 경우 다른 사이트(Cross-Site), eTLD+1이 같은 경우 같은 사이트(Same-Site)로 분류한다. .com과 .org같이 도메인의 가장 마지막 부분을 TLD(최상위 도메인)이라고 하는데, eTLD리스트에서 정의되어있는 eTLD(유효 최상위 도메인)를 확인할 수 있다. 최상위 도메인과 이 왼쪽의 하위 도메인을 합쳐서 eTLD+1이라고 한다. 

foo.appspot.com 과 bar.appspot.com 은 다른 사이트이다. eTLD가 같지만(appspot.com) eTLD+1은 다르다.

eTLD+1을 확인하여 같은 사이트, 다른 사이트를 분류하고 SameSite값을 통해 쿠키를 보낼 옵션을 설정한다.

 

쿠키의 한계점

쿠키는 서버가 아닌 클라이언트(브라우저)에 데이터를 저장한다는 것이 존재 이유이며, 동시에 보안이 취약점이기도 하다. 그래서 개인정보와 같은 민감한 정보는 쿠키에 저장하지 말아야 한다. 쿠키는 내가 사용중이 아닐 때에도 오랜 시간 유지되고, 접근이 쉽기 때문에 쿠키를 인증 수단으로 사용하면 안된다. 다른 사람이 쿠키를 쉽게 탈취하여 유저인 척 서버에게 요청하는 등 악용될 수 있기 때문이다.

또한 브라우저가 자동으로 매 요청마다 쿠키를 전송하기 때문에 반복적으로 전송할 필요가 없는 데이터는 쿠키보다는 로컬스토리지 또는 세션스토리지에 저장하는 것이 유리하다. 당장 필요하지 않은 다량의 데이터를 매번 전송하는 것은 네트워크 대역폭 낭비이다.

따라서 사용자 인증을 위해서 세션 방식과 토큰 방식을 많이 사용한다.

 

Session(세션) 인증 방식

세션은 쿠키와도 밀접하게 연관된다. 쿠키에 대해서 다음의 포스팅에서 다루었다. Cookie란, 쿠키 옵션 종류 HTTP는 stateless하다 HTTP는 웹 서버와 웹 브라우저가 데이터를 주고받기 위한 약속이다. H

hahagarden.tistory.com

 

Reference

코드스테이츠 학습자료

https://www.daleseo.com/http-cookies/

 

반응형

'개발 > CS, Network' 카테고리의 다른 글

개발 프로세스, DevOps, CI/CD, GithubAction  (0) 2023.06.05
Session(세션)  (0) 2023.05.06
HTTP란, HTTP message, stateless  (0) 2023.04.21
SOP와 CORS  (0) 2023.04.04
REST API, REST 성숙도 모델  (0) 2023.03.29
댓글