728x90

출처-xe.rigvedawiki.net


web프로그래밍을 하다보면 비교적 이른 타이밍에 배우게 되는것이 쿠키이다.

이름의 유래는 매직 쿠키라는 데이터 패킷의 이름에서 유래된 것이며 매직 쿠키는 운세가 적힌 쪽지가 담긴 포츈쿠키에서 유래한 것이다.

하지마 뭔가 직관적인 이름은 아닌거 같다. 원래 프로그래머들이 만든 용어중에 직관적이지 않은 용어들도 많다.

아들이 코끼리 장난감을 부르던 발음에서 시작된 하둡이라던가...(high availity 어쩌구 저쩌구는 뒤에 그냥 갖다붙힌 말이다.)


여튼 쿠키는 엄청 유명하지만 대부분의 학부생들은 그냥 좀 대충 사용하다가 넘어간다.

그래서 필자도 잘 모르고 있었던 부분들이 있었다.

이번에는 엄청 깊게 까지는 아니지만 어떻게 사용하는지에서 한번 이야기하고 넘어갈려고 한다.


쿠키가 뭐야?

쿠키는 각각의 브라우저에서 각각의 host별로 사용자의 컴퓨터에 db형태로 저장된 key-value형식의 데이터 묶음이다.

이렇게 말하면 뭔가 정떨어져 보이니까 쉽게 이야기하자면

클라이언트에 저장되는 데이터로 이해해도 무리는 없다.

지금은 간략하게 설명하니까 여러분들이 간과하고 갈 수 있는게 위의 설명이 중요하다.


1.각각의 브라우저별로 저장되며

2.각각의 host(사이트)별로 저장되며

3.db형태로(chrome의 경우 sqlite db형태)

4.key-value형태로 저장된다.(key와 value모두 문자열만 저장가능, 꼼수쓰면 객체도 가능하지만 불가능이라 보는게 편함)


일단 여기에 대해서는 추후에 다시 언급하고 일단


쿠키는 왜 존재하는가?


일단 모든 것은 왜 존재하느냐라는 근본적인 질문으로 시작해야한다.

서버와 클라이언트는 기본적으로 단발성통신이다.

한번 연락하면 끝나는 것이다.

이 때 서버는 클라이언트가 요청한 데이터를 던져주지만

이 데이터는 한번 보는 걸로 끝날 뿐, 클라이언트(사용자)측에 저장되지는 않는다.


아니 클라이언트 측에 저장할 데이터가 있어?라고 묻는다면,

당연히 엄청 많다고 할 수 있다.


가령 예를 들어보자. 특정 인물이 오늘 첫번째 접속인지 아닌지 알려면 어떻게 해야할까?

여기서 강력한 전제조건.


서버는 클라이언트가 주는 자료 아니면 아무것도 모른다. 또한 클라이언트가 주는 자료를 충실히 믿는다.

이를 이해해야한다.

오늘 첫번째 접속인지 아닌지는 일반적으로 서버는 죽었다 깨어나도 알 수 없다.


그래서 사용하는게 쿠키이다. 서버에 사용자가 접속했을 때 해당 쿠키의 존재여부를 확인한다.

해당 쿠키가 존재할 경우 재방문으로 취급, 존재하지 않으면 처음 방문으로 취급한다.


이런식으로 서버가 사용자의 컴퓨터에 자신이 원하는 정보를 입맛대로 남길 수 있다.


우리는 프로그래머이므로 코드를 잠시 보도록하자.


Cookie c = new Cookie("id", "jsp");
response.addCookie(c);

쿠키를 만들어서 발송하는 코드는 jsp의 경우 위와 같다.

정말 간단한데 위의 데이터는 id=jsp라는 코드이다.

이 쿠키의 이름은 id고 내용은 jsp이다.

그리고 마지막에 response객체에 실음으로써 사용자에게 전달된다.


응답부분을 보면 이렇게 Set-Cookie로 쿠키가 사용자의 컴퓨터에게 날라갔다는걸 확인시켜준다.


일단 이렇게 되면 더 이상 서버의 손을 떠난다.

사용자의 컴퓨터에 다운 로드 되었으므로 사용자가 직접 조작할수도 있다.

가령 js코드로 쿠키를 가져올 수도 있다.

이 부분은 쿠키를 처음 배우는 사람입장에서는 잘 모를 수도 있을것 같으므로

필요한 지식만 주입하는게 옳다는 필자의 판단으로 인해서 여닫는 문구로 대체하겠다.



여튼 이렇게 되면 사용자의 컴퓨터에 저장이 된거다.

이 쿠키를 우리가 수정도 할수 있고 삭제도 할 수 있다.

삭제하는 가장 쉬운 방법은 브라우저의 기능을 사용하는 것이다.



물론 우리는 프로그래머니까 소프트웨어 적으로도, 아니면 db에 직접 가서 삭제해도 된다.

사용자의 컴퓨터에 어디에 저장되는지는 아래를 확인하라.



아 이제 알겠어, 그럼 서버에서는 쿠키를 어떻게 쓰는거야?

일단 쿠키가 클라이언트에 생긴건 알겠다.

그럼 서버에서는 쿠키를 언제 가져가고 어떻게 쓰는지에 대한 질문이 들어야 정상이다.

뭐 비정상이라도 상관없다.


이제 부터 모든 요청에서 내가 만든 쿠키를 함께 보낸다.

예를들어서 여러분이 google에 들어가서 만들어진 쿠키는 구글에 접속할때 몽땅 묶어서 함께 보낸다.

모든 요청에 쿠키를 포장해서 보내는 것이다.


다행히도 다른 url(host, 사이트)에서 만든 쿠키를 보내지는 않는다. 그것까지 다보냈으면 박터졌을 것이다.

정확히 말하면 다른 url에 있는 쿠키는 건드릴 수가 없다. 보안정책상 그러하다.


이제 어떤 사이트를 가던 쿠키를 몽땅 담아서 요청에 넘기게 된다.

그럼 쿠키가 많으면 많을수록 자연히 http콜의 부담은 증가하게 된다.

그래서 쿠키는 용량 제한, 시간제한, 갯수 제한이 있다.


용량은 보통 3kb정도이고 갯수는 30~50사이로 브라우저마다 다르다.

시간제한의 경우 설정안하면 브라우저가 종료되는 즉시 삭제된다.

대신 시간제한을 더 늘리게 되면 엄청난 혜택이 주어지는데...


쿠키에 시간제한을 설정하면 브라우저가 종료되도 데이터가 유지된다.

db형태로 저장된다는 점에서 캐치를 했을 테지만 시간 제한을 지정하면 브라우저가 종료되도 데이터가 유실되지 않는다.

즉 목숨을 3일로 지정하면 3일동안은 브라우저가 종료되도 생존한다는 이야기.


이렇게 생존해있는 쿠키는 브라우저나 서브파티 라이브러리를 통해서 볼수있다.

아래는 크롬에 현재 생존한 쿠키를 보여주는 예제이다.



그럼 이 쿠키들을 서버에서 보려면 어떻게 해야할까?

뭐 답은 간단한데 서버에서 각각 제공해주는 로직이 있다.

그냥 api를 호출하면된다. 일단 만들어진 쿠키는 우리가 명시적으로 사용하지 않아도 항상 쿠키를 같이 받고 있으므로

그런 고민은 할 필요가 없다.


Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {
System.out.println(cookie.getName() + ":" + cookie.getValue());
}

jsp에서는 cookie를 몽땅 호출해서 for문으로 순회하면서 보여줄 수 있다.


이 쿠키는 웹에서 클라이언트 사이드에 저장하는 매우 중요한 녀석이지만 하나큰 문제점이 있다.


남도 읽을 수 있음

좁은 의미로는 컴퓨터에 침입해서 읽겠지만 넓은 의미로는 스크립트 인젝션처럼 js코드를 삽입하여 읽을 수 있다.

이는 매우 치명적이다. 크롬익스텐션에 악성코드 하나밖으면 내 cookie를 다 뺏겨 먹을수도 있다.

이를 제도적으로 막을 방법은... 없다.

그래서 이를 만드는 사람이 쿠키를 무제한적으로 생성하고 거기에 내 정보를 실어서 둔다면 장기적으로 보면 위험할 수 있다.

그래서 남이 못읽게 만드는 cookie도 있다. 이를 http only cookie 혹은 session cookie 등이라고도 불리는데 뭐라고 부르건 상과없다.


여기서 잘보면 스크립트에 엑세스 가능이라는 항목에 허용안함이라고 되어있다.

이 경우 스크립트로는 읽을 수 없게된다.

일반적으로 jsp에서 쓰는 JSESSIONID는 자동으로 http only cookie가 된다.

물론 코드로 설정하는 것도 가능하다.



그래도 쿠키에 중요한 데이터는 저장하지 않는게 좋다.

쿠키가 어느정도는 암호화해서 저장되지만 사실 암호화라기 보단 바이너리화에 가깝고 작정하면 쉽게 원문을 볼 수 있다.

쿠키를 빼내는 작업도 해커입장에서 만만한 작업은 아니겠지만 서버를 뚫는 방법에 비하면야...

게다가 위에도 말했지만 스크립트 인젝션으로는 손쓰지 않으면 손쉽게 빼낼 수 있다.


이상으로 쿠키에 대한 모든 설명을 마치도록 하겠다.

+ Recent posts