[Network] Cookie와 Session
이 글은 공부를 하면서 알게 된 내용들을 기록하는 글 입니다. 오류나 고쳐야 할 사항들이 있다면 지적 부탁드립니다!
웹 개발을 하면서 사용자의 정보를 저장해놓기 위해 Session과 Cookie을 사용합니다.
Session은 서버에 데이터를 저장해놓는 방식이며, 사용자가 브라우저를 닫을 때 모든 데이터가 삭제되는 임시(Temporary) 특성을 띄고 있습니다.
Cookie는 사용자의 컴퓨터에 데이터를 저장하는 방식이며, 브라우저를 닫아도 데이터가 유지되는 장점이 있지만, session에 비해 보안에 취약하다는 단점이 있습니다.
두 방법 모두 사용자가 웹사이트를 이용할 때, 사용자를 추적(track)하거나 관리(manage)할 때 도움을 줍니다.
두 방법에 대해 자세히 알아보고, 차이점을 알아보도록 합시다.
✅ Session
🔥 Session이란?
웹 개발에서의 Session은, 사용자가 웹 사이트 혹은 웹 어플리케이션과 상호작용하는 데에 필요한 정보들을 저장하는 방법들 중 하나를 이야기합니다.
사용자가 웹 사이트에 방문했을 때 `웹 서버는 해당 사용자에게 session을 생성`할 수 있으며, 해당 session에는 사용자의 로그인 상태, 장바구니 등 서비스 사용에 필요한 정보들을 담을 수 있습니다.
웹 서버가 사용자에게 session을 생성해준다고 했는데, 해당 session이 그 사용자의 것이라는 것은 어떻게 확인할 수 있을까요?
서버에서는 사용자에게 session을 생성할 때 각 사용자마다 `고유한(unique) session ID`를 발급하며, 이 `session ID`를 통해 session을 구별할 수 있습니다.
`session ID`는 `URL의 파라미터로 전달`하거나 `cookie에 저장`해두었다가 전달합니다.
Session을 통해 각 사용자에게 특화된(개인화) 경험을 제공할 수 있는데,
"HEY님 안녕하세요!"와 같이 닉네임과 함께 인사말을 보여준다던지, 장바구니에 구매하고자하는 물건을 넣어놓는 등의 활용이 가능하며,
이 외에도 보안에 필요한 별도의 조치를 취할 수도 있습니다.
Session은 사용자가 컴퓨터를 종료하거나 프로그램에서 로그아웃 시, 세션에 저장되어 있던 값들은 자동으로 삭제됩니다.
또한 Session은 브라우저에 열려 있는 여러 페이지들 간에 같이 사용될 수 있습니다.
Session이 어떻게 동작하는지 로그인 과정을 예로 들어 설명해보겠습니다.
🔥 Session 방식의 로그인 과정
- 사용자 이름이 HEY인 사용자가 로그인을 할 때, 유저명과 비밀번호를 서버에 보냅니다.
- 비밀번호 정보가 맞는 경우 서버는 `Session DB`에 HEY라는 사용자를 생성합니다.
이 때, 사용자에게 고유의 `SessionID`를 발급함과 동시에 `Session DB`에 {고유의 SessionID} - {사용자 이름}을 매칭시켜 저장합니다. - 발급한 `SessionID`는 Cookie를 통해 전달하고, 해당 브라우저의 쿠키에 저장됩니다.
- 사용자가 웹사이트를 이용하며 요청(Request)를 보낼 때마다 브라우저 내에 SessionID가 저장되어 있는 쿠키도 같이 보냅니다.
(Cookie는 요청;Request 시 항상 자동으로 같이 전송됩니다.) - 서버에서는 들어온 Cookie로부터 `SessionID`를 추출합니다.
(이 때까지는 서버도 요청한 유저가 어떤 사용자인지 확인하지 못한 상태입니다. 그저 `SessionID`가 있는 Cookie가 요청을 통해 같이 전달되었다는 사실만 압니다.) - `SessionID`를 바탕으로 `SessionDB`를 확인하고, SessionID와 매칭되어 있던 사용자 이름을 확인합니다.
이 때, 서버는 요청한 유저가 어떤 사용자인지 알게 됩니다. - 이를 바탕으로 "환영합니다 HEY님!"과 같이 사용자 맞춤 응답을 전달할 수 있게 됩니다.
- 해당 요청이 끝나고 다른 페이지로 이동하게 되면 4~7번의 과정을 반복합니다.
🔥 Session의 특징
- 장점
사용자와 관련된 정보를 사용자가 들고 있지 않습니다. 사용자가 가지고 있는 것은 오직 `SessionID` 뿐입니다.
Cookie는 여기에서 SessionID를 전달하기 위한 매개체로 사용됩니다.
따라서 외부의 공격으로 인해 Session이 탈취되어도, 해당 Session 만으로는 공격자가 사용자의 정보에 대해 알아낼 수 있는 것이 없습니다.
(사용자의 정보를 모두 서버에 저장되어 있기 때문이죠)
또한 블랙 리스트의 강제 로그아웃과 같은 처리가 가능합니다.
우리가 자주 사용하는 서비스에서도 찾아볼 수 있는데요, 넷플릭스 & 티빙에서의 접속 가능 대수 제한, 특정 디바이스에서의 강제 로그아웃과 같은 작업이 가능합니다.
토큰을 사용한 로그인의 경우에는 유효성만을 확인하기 때문에 로그아웃을 강제할 수 있는 방법이 없습니다.
- 단점
Session의 큰 단점이 있습니다. 바로 로그인 한 사용자들의 모든 `SessionID`를 Session DB에 저장해놔야 한다는 것입니다.
요청(Request)가 들어올 때마다 서버는 쿠키를 통해 `SessionID`를 파악하고, Session DB를 통해 SessionID와 일치하는 사용자를 찾고, 그제서야 다음 작업을 진행할 수 있습니다.
즉, 요청이 있을 때마다 DB에 접근해야 합니다.
사용자가 늘어남에 따라 DB 리소스 또한 늘어나게 되고, 서버에 부하가 갈 수 있다는 단점이 있습니다.
🔥 규모가 커져 서버가 여러 개가 되었을 때의 세션 관리법? (작성 중)
Session은 DB를 통해 조회를 해야 하기 때문에, 서버가 여러 개가 되었을 때 Session을 관리하는 법을 고민해봐야 합니다.
✅ Cookie
🔥 Cookie란?
HTTP Cookie(웹 쿠키, 브라우저 쿠키)는 사용자의 컴퓨터에 저장되는 작은 text file로, 최대 크기는 대략 4KB 정도 됩니다.
사용자가 웹 사이트에 방문했을 때, 서버는 사용자의 웹 브라우저에 Cookie 형태로 저장하게 되는데 이를 통해 사용자의 정보를 저장할 수 있습니다.
`key-value` 형식의 String 데이터로 저장되며, 서버는 `HTTP Response Header`의 `Set-Cookie` 속성을 통해 클라이언트에게 cookie를 제공할 수 있습니다.
데이터가 사용자의 PC에 저장되기 때문에 임의로 수정하거나 중간에 가로채기 쉬워 보안에 취약하다는 단점이 있습니다. 따라서 쿠키에는 보안에 민감하거나 중요한 정보를 담는 것은 지양하는 것이 좋습니다.
이를 통해 로그인 상태 유지, 장바구니와 같은 서비스를 사용자에게 제공할 수 있습니다.
HTTP는 본래 Stateless(상태가 없는) 프로토콜로, 사용자가 연속으로 요청(Request)를 해도 서버는 기본적으로 사용자가 누구인지 모르며, 사용자에 대한 데이터를 지니고 있지 않습니다.
흠.. 그렇다면 네이버 쇼핑에서 장바구니에 사고자하는 물건을 담은 후, 다른 페이지로 이동했을 때를 예로 들어볼까요?
다른 페이지로 이동하면서 새로운 API를 요청했을텐데, 장바구니에는 우리가 담은 물건이 그대로 담겨 있습니다.
이것이 바로 Cookie의 활용을 통해 제공할 수 있는 서비스입니다.
HTTP는 Stateless 프로토콜이지만 Cookie에 사용자의 정보를 저장해둠으로서, 장바구니와 같은 기능을 제공할 수 있는 것입니다.
🔥 Cookie의 지속시간
- 세션 쿠키(Session cookie)
`Max-Age` 혹은 `Expires` 속성이 없는 쿠키의 경우 현재 session이 끝날 때 같이 삭제됩니다.
브라우저마다 "현재 session"이 언제끝나는지 정의하며, 몇몇 브라우저는 브라우저를 재시작할 때 "세션 복구"를 하기도 합니다. - 영속적인 쿠키(Permanent cookie)
`Max-Age` 혹은 `Expires` 속성에 값을 명시하여 cookie를 언제 삭제할지 명시할 수 있습니다.
유효기간이 지나면 cookie는 자동으로 삭제되며 요청(Request)시에 같이 전송되지 않습니다.
cookie가 생성될 때 `Set-Cookie` 헤더에 어떤 속성의 값들이 있는지 확인하여, 해당 쿠키가 session cookie인지 permanent cookie인지 확인할 수 있습니다.
🔥 Cookie의 활용 & 특징
- 같은 도메인끼리만 Cookie 전달이 가능하다.
Cookie는 같은 도메인 사이에만 전달이 가능합니다. 예를 들어 Youtube에서 발급한 Cookie는 Youtube로만 전달이 가능합니다.
배포 할 때 이러한 경험을 할 수 있었는데요,
프로젝트에 JWT를 도입하면서 쿠키를 통해 Refresh token을 전달했습니다. localhost를 통해 서버를 돌릴 때에는 문제가 없었지만, 배포를 진행하며 프론트와 백의 배포 주소가 달라지며 쿠키가 전달되지 않는 문제가 발생했습니다. (결국 도메인 적용을 통해 프론트와 백의 배포 도메인을 맞춰줌으로서 해결했습니다 :D) - Token 로그인 방식에 사용된다.
방금 위에서 이야기했다시피, Token을 활용한 로그인을 사용하는 경우 Cookie를 통해 Token 정보를 전달하기도 합니다. - Session 관리에 사용된다.
위에서 Session에 대해 설명했던 내용과 같이, Session을 이용한 로그인 방식을 사용한다면 SessionID를 Cookie를 통해 전달하게 됩니다.
이 외에도 장바구니, 게임 스코어 등의 정보를 관리할 수 있습니다.
✅ HTTP의 특징: Stateless
🔥 Stateless란?
HTTP는 Stateless. 즉, 상태를 가지고 있지 않습니다.
더 자세한 이야기는 밑의 포스팅에 작성했으니 참고 부탁드립니다 :)
https://m42-orion.tistory.com/106
🔥 Stateless의 의미를 살펴보면, 세션은 적절하지 않은 인증 방법이 아닐까? (작성 중)
✅ Session vs Cookie 표로 보기
세션 (Session) | 쿠키 (Cookie) | |
보안 | ||
속도 | ||
용량 | ||
만료기간 | ||
저장 형식 |
✅ 참고 자료 & 링크
- Difference between Session and Cookies - GeeksforGeeks
- 세션 vs 토큰 vs 쿠기? 기초 개념 잡아드림. 10분 순삭! - 노마드 코더
- https://github.com/VSFe/Tech-Interview/blob/main/03-NETWORK.md
- What Are Sessions? How Do They Work? - Baeldung