💋 쿠키는 왜 필요할까?
쿠키의 개념이 등장한 배경을 이해하기 위해서는, 먼저 클라이언트와 서버의 구조에 대해 이해할 필요가 있다.
클라이언트가 서버에 요청을 보내고, 서버로부터 오는 응답을 대기한다.
서버는 들어온 요청에 대한 결과를 만들어서 응답을 보내준다.
✔ 무상태(Stateless)
그런데, 이 때 서버는 클라이언트의 상태를 보존하지 않는다. 이 특성을 Stateless라고 한다.
예를 들어서, 로그인 페이지에서 HTTP 요청을 하면, 서버에서 요청을 처리하고 응답을 보낸다. 그렇게 되면 서버와 브라우저의 연결은 끝이다.
또 로그인을 끝낸 후에 home 화면으로 가게 되면 GET 요청을 보내게 되면, 백엔드가 html을 렌더링하고 끝나게 된다. 더이상의 연결은 없다.
이처럼 클라이언트와 서버는 요청과 응답을 주고 받으면 연결이 끊어진다.
클라이언트가 다시 요청을 하면 서버는 이전 요청을 기억하지 못한다.
클라이언트: 나 이름 깃짱이고 비번 xxxx임!
서버: ㅇㅋ 로그인 완료!
(잠시 후)
클라이언트: 나 회원 정보 조회할래!
서버: 누구세요?
따라서 서버는 기본적으로 브라우저를 기억하지 못한다.
이 때문에, 내가 로그인을 하겠다는 POST 요청을 보내고, 로그인이 성공적으로 완료되었다는 응답을 받았다 하더라도, 다른 요청을 보냈을 때는 서버는 내가 로그인된 유저라는 사실을 알지 못한다. 서버 바보ㅠ
따라서 우리는 유저에게 어떤 정보를 추가적으로 남겨줘야 한다.
브라우저가 서버에 뭔가 요청할 때마다 누가 요청했는 지 알 수 있도록 말이다!
클라이언트: 나 이름 깃짱이고 비번 xxxx임!
서버: ㅇㅋ 로그인 완료!
(잠시 후)
클라이언트: 나 이름 깃짱이고 비번 xxxx인데, 회원 정보 조회할래! (추가 데이터 제공)
서버: 깃짱의 회원정보-
✔ 무상태(Stateless)를 해결하려면 모든 요청에 사용자 정보를 포함하면 된다?!!
그냥 계속 모든 요청에 '나 이름 깃짱이고 비번 xxxx인데'를 포함하면 되는 일이다!
하지만, 모든 요청에 사용자 정보를 넣도록 추가하는 것은 보안 측면에서도 좋지 않고, 개발할 때에도 힘들다...
아주 구린 해결방안이다...
이걸 해결하기 위해서 쿠키라는 개념이 도입되게 되었다!
💋 쿠키를 사용한다면..?
먼저, 쿠키와 관련된 헤더 두 가지를 살펴보자
✔ Set-Cookie 헤더
- Response에서 사용
- 서버에서 클라이언트로 쿠키 전달
✔ Cookie 헤더
- Request에서 사용
- 클라이언트가 서버에서 받은 쿠키를 저장
- 요청 시에 서버로 전달
✔ Cookie를 사용한 요청과 응답의 흐름
1. 브라우저가 서버에 요청을 보낸다.
브라우저: 내 이름 깃짱이고 비밀번호 xxxx인데, 로그인 시켜줘! [POST 요청]
POST /login HTTP/1.1
user=깃짱&password=xxxx
2. 서버는 받은 정보를 바탕으로 쿠키를 만들고, 브라우저에게 Set-Cookie 헤더를 통해 응답에서 쿠키를 함께 보낸다.
HTTP/1.1 200 OK
Set-Cookie: user=깃짱
스타라이토 깃짱 로그인 성공!
3. 웹 브라우저 내에는 쿠키 저장소가 있다. 그 저장소에 응답의 Set-Cookie 헤더를 통해 받은 쿠키를 저장한다.
4. 브라우저는 이후에 서버에 다시 요청을 할 때, 쿠키 저장소에서 쿠키를 조회해서, Cookie 헤더를 통해 함께 보낸다.
브라우저: 나 다시 로그인할래! here is my cookie!
GET /welcome HTTP/1.1
Cookie: user=깃짱
서버는 쿠키를 통해서 브라우저를 구분할 수 있다.
[개인적 궁금증] 클라이언트와 브라우저.. 계속 혼용되어서 사용되는데, 같은 말로 이해해도 될까?
클라이언트와 브라우저는 다른 개념이다.
브라우저는 인터넷에서 정보를 검색하고 보여주는 소프트웨어이며, 클라이언트는 서버에게 정보를 요청하는 컴퓨터 또는 소프트웨어이다.
하지만 대부분의 경우, 브라우저는 클라이언트의 역할을 수행한다.
즉, 브라우저는 사용자가 웹 페이지를 요청하고 서버로부터 정보를 받아오는 클라이언트의 역할을 한다.
따라서 일반적으로 브라우저와 클라이언트를 같은 의미로 이해해도 무방하다.
그러나 엄밀한 의미에서는 브라우저와 클라이언트는 다른 개념이다.
[개인적 궁금증] 쿠키를 요청에 별도로 포함해야 할까?
쿠키는 모든 요청에 자동적으로 포함된다.
극단적으로 쿠키가 100개면, 모든 요청에 쿠키 100개는 자동으로 추가된다.
따라서 사용자의 모든 요청에, 개발자들은 별도로 쿠키 정보를 포함하려는 노력을 하지 않아도 쿠키는 자동적으로 포함된다.
하지만, 보안상으로 모든 곳에 쿠키를 함께 보내면 문제가 생길 수 있기 때문에 제한할 수 있다.
💋 쿠키의 구조를 뜯어보자
위에서는 'user=깃짱' 이라는 내용을 그대로 쿠키에 넣어버렸지만, 실제로 그렇게 하면 위험하다. 개인정보 빼기!
✔ 세션이란? (session)
실제로는 로그인이 성공하면, 서버는 실제 정보를 쿠키에 넣는 대신 session id라는 것을 만든다.
또 이 세션을 잊지 않기 위해서 로그인 정보를 서버의 DB에 저장한다.
그리고 민감정보를 쿠키에 넣는 대신, session id만을 쿠키에 넣어서 클라이언트에 반환한다.
세션은 백엔드와 브라우저 간에 어떤 활동을 했는지 기억하는 것을 말한다.
내가 현재 어떤 사이트에 로그인이 유지되고 있다면, 현재 사용하고 있는 브라우저와 내가 만든 백엔드 사이에 세션이 존재하는 것이다.
세션은 브라우저와 서버 사이의 memory, history 같은 것이다.
✔ 쿠키의 생명주기란? (expires)
expires 뒤에 적힌 것은 생명 주기이다.
만기일이 되면 쿠키가 삭제된다.
또 max-age로 쿠키가 살아있을 시간을 초 단위로 넣어줄 수 있는데 0이나 음수를 지정하면 쿠키가 삭제된다.
쿠키의 생명주기에 따라서 두 가지로 분류할 수 있다.
- 세션 쿠키: 만료 날짜를 생략하면 브라우저 종료까지만 유지
- 영속 쿠키: 만료 날짜를 입력하면 입력한 날짜까지 유지
✔ 쿠키에 도메인을 지정할 수 있다. (domain)
내가 만든 쿠키가 아무 사이트에나 막 들어가면 난감하다. 따라서 쿠키를 같이 보내줄 도메인을 지정할 수 있다.
domain=gitchan.org로 지정하면, 명시한 도메인 + 서브 도메인에 쿠키가 전달된다.
여기서 서브 도메인 에시로는 starlight.gitchan.org 같은 도메인이 있을 것이다.
도메인을 생략하면, 현재 문서 기준 도메인에서만 적용된다.
gitchan.org에서 쿠키를 생성했다면, gitchan.org 서버에서만 쿠키에 접근할 수 있고,
starlight.gitchan.org에서는 쿠키에 접근하지 못한다.
✔ 쿠키에 경로을 지정할 수 있다. (path)
도메인으로 먼저 한 번 필터링 한 후에 도메인 내부의 경로로 추가 필터링을 할 수 있다.
지정한 경로를 포함한 하위 경로 페이지에만 쿠키가 접근할 수 있다.
✔ 보안
Secure, HttpOnly, SameSite 등을 지정할 수 있다.
💋 쿠키를 사용한 방법의 사용과 주의사항
쿠키는 위에서 살펴봤듯 사용자의 로그인 세션을 관리하는데 사용된다. 또 이 사용자가 어떤 광고를 좋아하는지에 대해서 살펴볼 때도 유용하다.
하지만 쿠키도 단점이 있다.
네트워크 트래픽이 추가되기 때문에, 세션 Id라던가, 인증 토큰이라던가 정말 최소한의 정보에만 사용하는 것이 좋다.
매번 서버에 쿠키를 전달하지 않고, 웹 브라우저 내부에 데이터를 저장해놓고 싶으면 localStorage를 사용하면 된다.
또 보안에 민감한 데이터는 쿠키에 절대절대절대절대 저장하면 안된다!!!
'WEB > HTTP' 카테고리의 다른 글
[HTTP] Cache-Control: 웹 서비스 캐시(Cache) 다루기 (2) | 2023.09.05 |
---|---|
[HTTP] HTTP 기본 인증 (Basic Authentication): 개념과 사용 방법 (1) | 2023.05.02 |
[HTTP] 상태 코드(Status Code): 상태 코드는 왜 필요할까? 상태 코드의 개념과 종류 (0) | 2023.04.27 |
[HTTP] 요청(Request)과 응답(Response): Header와 Body에는 어떤 내용이 들어있을까? (0) | 2023.04.17 |