우리가 물건을 구매하기위해 매장에 방문할 때, 우리는 점원과 다음과 같은 대화를 주고 받을 것 입니다.
고객: 이 사과 얼마인가요?
점원: 한개 1000원 입니다.
고객: 2개 구매할게요.
점원: 2000원입니다. 카드, 현금중 어떤걸로 결제하시겠어요?
고객: 카드로 구매할게요.
점원: 2000원 결제 완료되었습니다.
이런 대화가 가능한 것은, 점원이 고객과 주고받았던 정보를 기억하고있기 때문입니다. 이러한 상태를 "Statful하다"라고 합니다.
반면 Http 프로토콜은 Stateless, 무상태 프로토콜입니다. 즉 사용자와 서버간의 대화에서 서버는 사용자와 주고받은 정보를 전혀 기억하지 못합니다. 만약 고객과 점원이 Stateless한 상태로 대화를 주고 받는다면 다음과 같은 대화가 오고 갈 거에요.
고객: 이 사과 얼마인가요?
점원: 한개 1000원 입니다.
고객: 2개 구매할게요.
점원: ? 무엇을 2개 구매하시겠어요?
고객: 카드로 구매할게요.
점원: ? 무슨 제품을 몇 개 카드로 구매하시겠어요?
고객: ... (집에간다)
정상적인 서비스 이용이 불가능 한 것이겠죠.
때문에 고객은 전에 무슨 대화를 나누었던 항상 필요한 모든 정보를 이야기 해야합니다.
고객: 이 사과 얼마인가요?
점원: 한개 1000원 입니다.
고객: 이 사과 2개 구매할게요.
점원: 2000원입니다. 카드, 현금중 어떤걸로 결제하시겠어요?
고객: 이 사과 2개를 카드로 구매할게요.
점원: 2000원 결제 완료되었습니다.
이러한 무상태 프로토콜은 사용자 입장에서는 굉장히 불편하게 보이지만, 개발자 입장에서는 서버를 확장이 용이하는 등등 여러모로 강력한 장점이 있습니다.
쿠키는 사용자의 컴퓨터에 저장되는 작은 기록 저장소입니다.
사용자와 서버가 대화를 주고받으면서 서버가 기억해야 할 정보를 듣게되면 서버는 쿠키에 그 정보를 담아 사용자의 브라우져로 하여금 쿠키를 저장하도록 지시합니다.
서버는 Http 응답 메세지에 Set-Cookie 신호를 보내 사용자의 브라우져가
쿠키를 생성하도록 지시합니다.
쿠키를 받은 사용자 브라우져는 앞으로 서버와 하는 모든 대화에 저장된 쿠키를 실어 보내게 됩니다.
사용자가 "2개 구매할게요" 라고만 말해도 쿠키에 담긴 "이 사과, 카드 결제"가 함께 전달 되기 때문에 서버는 "이 사과 2개 카드로 구매할게요"라고 이해할 수 있게되는 것입니다.
이는 로그인을 필요로하는 서비스에서 굉장히 유용하게 사용됩니다.
홍길동 손님이 로그인을 하기 위해 서버에 접근했다고 생각해봅시다.
홍길동님의 로그인 정보가 서버에 전송되고, 서버는 이 정보를 쿠키에 실어 사용자에게 반환한다. 사용자의 브라우져는 쿠키를 저장한다.
이후 사용자가 하는 모든 요청에는 쿠키가 실려 보내진다.
쿠키의 생명주기는 쿠키를 생성할 때 정해집니다.
세션 쿠키: 브라우져가 종료되면 함께 삭제되는 쿠키.
Set-Cookie: user=홍길동
영속 쿠키: 일정 시간이 지난 뒤에 자동으로 만료되는 쿠키.
Set-Cookie: user=홍길동; expires=Sat, 26-Dec-2020 04:39:21 GMT
Set-Cookie: user=홍길동; max-age=3600 (3600초)
위 처럼 쿠키를 생성 할 때 만료 날짜를 입력하면 영속 쿠키가, 입력하지 않으면 세션 쿠키가 생성됩니다.
네이버에 로그인해 만들어진 홍길동님의 쿠키가 유튜브 서버에 전송되는 일이 없도록, 쿠키에는 특정 도메인을 지정해 줄 수 있습니다.
set-cookie: user=홍길동; domain=naver.com;
위처럼 도메인을 지정해주면, 도메인과 그 서브 도메인에만 쿠키가 전송됩니다.
만약 도메인을 지정하지 않으면 쿠키를 생성한 도메인만 접근이 가능합니다. 단 이 경우 서브 도메인(ex) dev.naver.com)에는 쿠키가 전송되지 않습니다.
위와 비슷하게 쿠키가 전송되는 URI경로 또한 지정해줄 수 있습니다.
set-cookie: user=홍길동; path=/service; domain=naver.com;
위처럼 경로를 지정해주면, 입력한 경로와 그 하위 경로에서만 쿠키가 전송됩니다.
하지만 일반적으로 경로를 지정하는 경우는 드물고, path=/ 즉 root로 지정합니다.
쿠키를 생성할 때 키워드를 입력하여 쿠키에 보안을 강화할 수 있습니다.
set-cookie: user=홍길동; path=/service; domain=naver.com; Secure
Secure
https인 경우에만 쿠키를 전송
HttpOnly
XSS 공격 방지
자바스크립트에서 쿠키 접근 불가
HTTP 전송에만 사용
SameSite
XSRF 공격 방지
요청 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키 전송
쿠키는 사용자 로그인 세션관리, 광고 정보 트래킹등 다양한 용도로 사용되는 편리한 기술이지만, 항상 서버에 전송되는 데이터기 때문에 최소한의 정보만을 저장하는 것이 권장됩니다.
또한 쿠키는 노출되기 쉬운 정보입니다. 아무리 조심한다 하더라도 Http message는 브라우져에서도 손쉽게 열어볼 수 있기 때문에 보안상 민감한 정보는 결코 쿠키를 통해 전송해선 안됩니다.
앞서 말씀드렸 듯, 쿠키에는 많은 정보를 담기 어렵고 보안에 취약하다는 한계가있습니다. 이러한 문제를 해결하기 위해서는 결국 실제 정보는 모두 서버에 저장하고, 사용자와는 임의의 식별자를 통해 소통해야합니다. 이러한 기술을 세션이라고 합니다.
이처럼 세션에는 아무런 정보가 없기 때문에 쿠키가 노출된다 하더라도 문제가 없습니다.
다만 쿠키가 털려 sessionId가 노출된다면 이를 악용해 Http 요청 메세지를 만들 수 있기 때문에 쿠키와 마찬가지로 만료 시간을 짧게 유지하는 것이 좋습니다.
<출처>