쿠키(Cookie) ?
개요
외국에서는 쿠키를 통에 담아두고 먹고 싶을 때마다 꺼내서 먹는다고 한다. 우리가 오늘 배울 쿠키(Cookie)의 이름의 유래라고 한다. 이번 포스팅에서는 쿠키가 등장하게 된 배경과 쿠키란 무엇인가에 대해 알아보고자 한다.
목차
- HTTP의 한계
- 쿠키(Cookie)
- 쿠키로 인증 상태 유지하기
- 주의점
HTTP의 한계
HTTP의 중요한 특징 중 하나는 Stateless(무상태)이다. HTTP에 대해서 모른다면 이전 포스팅을 참고하기를 바란다. 간단히 설명하자면 HTTP의 메시지들끼리는 공유 가능한 데이터(상태)를 갖지 않는 것이다. 이러한 특징은 사용자의 인증을 요구하는 웹서비스들이 나오면서 문제에 직면하게 된다. 다음과 같은 상황을 생각해보자.
- 철수는 옷을 사기위해 온라인 쇼핑몰인 "바니또 몰"에 접속하여 로그인을 했다.
- 마음에 드는 옷을 발견한 철수는 장바구니에 담고,
- 장바구니에 있는 옷들을 결제하였다.
위의 상황에서 철수가 바니또 몰 서버에 요청한 메시지는 총 3개로 다음과 같다.
- 철수의 계정 인증 요청(로그인)
- 철수의 장바구니에 옷을 담도록 요청
- 철수의 장바구니에 있는 옷들을 결제하도록 요청
HTTP의 Stateless 특징에 의하면 3개의 요청은 모두 별개로 처리되어야 하고, 2번 3번을 수행할 때 철수의 인증 정보를 매번 서버에게 보내주어야 한다. 왜냐하면 1번에서 인증한 데이터는 공유되지 않기 때문이다. 다른 사람이 아닌 "철수"의 장바구니에 담고 "철수"의 장바구니에 있는 옷들을 결제해야 하기 때문에 철수라는 인증은 필수적이다.
쿠키(Cookie)
쿠키란, 매 페이지에서 필요해서 불편할 수 있는 정보들을 클라이언트에서 보관하고 있다가 서버에게 요청을 보낼 때마다 자동으로 보내지게 하여, 직접 입력할 필요가 없도록 만든 도구이다.
쿠키는 흔하게 사용되고 있으며 오히려 사용하지 않는 곳이 드물다. 쿠키를 확인하고 싶다면 크롬의 경우 F12를 눌러 개발자 도구를 켠 후, Application 탭 -> Cookies 하위 쿠키들 을 차례로 클릭하면 볼 수 있다.
쿠키로 인증 상태 유지하기
우리가 로그인을 하고 웹 서핑을 하는 동안 다음과 같은 단계를 거쳐 자동으로 인증이 처리된다.
- 처음 로그인을 하면 서버가 인증정보를 확인하고 인증정보를 암호화한 데이터를 쿠키에 담아 클라이언트에게 전송한다. (Set-Cookie)
- 클라이언트는 서버의 응답을 받고 쿠키를 저장한다.
- 해당 서버에게 클라이언트가 요청을 보낼 때마다 쿠키를 자동으로 전송한다. (Cookie)
- 서버는 클라이언트로부터 받은 쿠키 안의 데이터를 복호화하여 인증정보를 확인한다.
쿠키의 구조
쿠키는 이름과 값 말고도 서버에게 여러 정보들을 알려준다.
- Domain : 해당 도메인과 그 하위 도메인에서만 접근이 가능하다. 명시되어 있지 않다면 쿠키를 만든 도메인만 접근이 가능하다.
- Path : 해당 경로를 포함하여 하위의 경로에서만 쿠키에 접근이 가능하다.
- Expires : 만료날짜. 해당 날짜 이후로 쿠키가 만료된다. 생략하면 브라우저 종료 시까지만 유지된다.
- Max-Age : 만료 시간. 초단위로 쿠키의 수명을 설정할 수 있다. 0이나 음수를 지정하면 쿠키가 삭제된다.
- HttpOnly : Http전송시에만 사용된다. Javascript로 접근할 수 없게끔 하여 XSS 공격을 방지한다.
- Secure : 이 옵션이 설정되어 있다면 Https의 경우에만 쿠키를 전송한다.
- SameSite : 요청을 보낼 서버의 도메인과 쿠키에 설정된 도메인이 같은 경우에만 쿠키를 전송한다. XSRF 공격을 방지한다.
주의점
쿠키를 사용할 땐 다음과 같은 사항들을 체크해야 한다.
- 쿠키는 항상 서버에 전송되기 때문에 많아지면 그 만큼 성능에 영향을 미친다. 따라서 인증정보와 같은 꼭 필요한 최소한의 정보만 저장하여야 한다.
- 만약 클라이언트에서 유지할 필요가 있는 데이터지만 서버에 항상 전송할 필요가 없다면 웹 스토리지(localStorage, sessionStorage)를 사용하도록 한다.
- 쿠키는 서버에서 관리하는 데이터에 비해 보안에 취약하다. 따라서 보안에 민감한 데이터(ex. 주민번호, 신용카드 번호 등)를 저장하면 안된다.
- 그래서 사용자의 인증정보도 서버에서 한번 암호화 하여 저장하는 것이다. 이것은 서버의 세션과 상호 작용을 하는데 추후에 포스팅하도록 하겠다.