favicon

Jayden { do: smite }

CS-Network. 쿠키와 세션에 대해

🧷 CS-Network 스터디

코드스쿼드 과정을 마치고 프론트엔드 개발자로서 알아야될 네트워크 지식을 채우기 위해 시작한 CS 스터디!<br/> Tech-Interview-Network를 참고하여 스터디를 진행하기로 했다.

1. 쿠키와 세션의 차이에 대해 설명해주세요.

먼저 쿠키와 세션은 모두 HTTP의 connectionless, stateless를 보완하기 위해 등장한 기술입니다.

단순하게 생각하면 쿠키는 클라이언트 측에 사용자 정보 등의 데이터를 저장하는 기술이고 세션은 서버 측에 데이터를 저장하는 기술입니다. 그렇기 때문에 서버의 과부하 면에서는 세션보단 쿠키가 유리하고 보안 면에서는 쿠키보단 세션이 유리합니다. 이 둘의 가장 큰 차이는 데이터가 유지되는 유효 시간 관리에 있습니다. 쿠키는 서버에서 쿠키를 만들 때 정한 유효시간 동안 계속 유지되지만 언제든지 클라이언트가 수정 및 삭제가 가능하다는 특징이 있습니다. 반면 세션은 클라이언트가 직접 데이터의 라이프사이클에 개입할 수 없으며 서버에서 정한 규칙에 따라서 세션이 만료된다는 특징이 있습니다.

용량, 서버 부하, 보안 등의 차이가 있지만 라이프 사이클에 대한 대답을 하는 게 가장 좋다고 한다!<br/> 세션 쿠키: 서버에서 쿠키를 만들 때, 유효시간을 지정하지 않은 경우로 브라우저를 닫으면 삭제된다.

1. 세션 방식의 로그인 과정에 대해 설명해주세요.

먼저 세션은 유저가 웹서버에 접속해 있는 상태를 하나의 단위로 한 개념입니다. 이 때, 각 단위인 세션에 대해 id를 부여한 것이 세션 id가 됩니다.

  • 클라이언트가 로그인 정보(유저id, 암호 등)와 함께 서버에 로그인 요청을 보냅니다.
  • 서버는 로그인 인증을 하고 해당 정보가 유효하면 세션 객체를 생성하여 해당 세션에 대한 id를 응답 헤더의 Set-cookie를 통해 전달합니다.
  • 클라이언트는 응답 헤더의 Set-cookie에 따라 쿠키 저장소에 세션 id를 저장하게 되고 이후 요청 시, 세션 id를 헤더에 담아 전달합니다.
  • 서버는 클라이언트가 요청과 함께 보낸 세션 id를 통해 관리 중인 세션에서 정보를 찾아 응답합니다.

세션 방식은 서버에 유저 정보를 세션으로 관리하기에 부하가 온다는 단점이 있다.<br/> 또한 서버를 확장할 때, 모든 서버가 세션을 공유 혹은 갖고 있어야하므로 비효율적일 수 있다.<br/> 유저의 정보를 서버에서 갖고 있다는 점은 일반적으로 보안이 좋다는 의미긴 하지만, 이건 어디까지나 서버가 보안이 잘 되어있을 때이다.<br/> JWT 로그인 방식과 자주 비교된다.

2. HTTP의 특성인 Stateless에 대해 설명해주세요.

상태를 갖고 있지 않다는 의미로 주로 서버에서 기억되어지는 데이터가 없음을 의미합니다. 즉, 클라이언트가 요청을 할 때마다 응답에 필요한 데이터를 매번 보내야합니다. 만약 이전 요청에서 전달받은 데이터를 기반으로 그 다음 요청에 응답을 한다면 이는 서버에서 상태를 유지하고 있는 게 됩니다. 이렇게 stateless하게 유지하면 언제든 서버를 대체할 수 있고 쉽게 확장할 수 있다는 장점이 있습니다.

3. Stateless의 의미를 살펴보면, 세션은 적절하지 않은 인증 방법 아닌가요?

stateless의 의미만을 살펴보면 세션은 stateless하지 않기에 적절하지 않다고 할 수 있습니다. 하지만 예를 들어 로그인 후 회원의 로그인 유무를 유지하는 기능을 구현할 때, HTTP의 stateless한 성질을 유지하면서 매 요청마다 회원의 로그인 정보를 전달하는 것은 효율적이지 않습니다. 이를 극복하기 위해 세션과 같은 state를 부여한 것이므로 기능의 효율면에서는 적절하다고 생각합니다.

4. 규모가 커져 서버가 여러 개가 된다면, 세션을 어떻게 관리할 수 있을까요?

특정 유저에 대해서는 고정된 서버를 사용하게끔하는 Sticky Session 방법이 있습니다. 로드 밸런서는 요청 헤더의 쿠키를 확인하고 쿠키가 존재하지 않으면 로드 밸런싱 알고리즘으로 해당 요청에 대한 서버를 부여하고 쿠키가 존재하면 이전에 통신했던 서버로 요청을 전달합니다. 하지만 이 방법 또한 서버 하나가 죽으면 유저가 재요청해야하고 우연히 특정 서버로 트래픽이 몰리는 경우가 생길 수 있는 단점이 있습니다.<br/> 가장 이상적으로 생각해보면 모든 서버를 하나의 서버처럼 다룰 수 있다면 위와 같은 문제들을 해결할 수 있게 됩니다. 이렇게 여러 대의 컴퓨터들이 하나의 시스템처럼 동작하도록 하는 것을 클러스터링이라고 합니다. 첫번째 클러스터링 방식으로 All-to-All 방식이 있습니다. 요청에 대한 세션을 특정 서버에 저장하고 저장된 세션 객체를 복제하여 모든 서버에 전달하여 보관합니다. 요청에 대해서 모든 서버가 동일한 응답을 할 수 있지만, 동일한 세션 객체를 모든 서버가 저장하고 있어야 하므로 메모리에 과하게 필요하다는 단점이 있습니다.<br/> 다음으로는 Primary-secondary 방식이 있습니다. 이는 세션 객체를 저장한 서버를 Primary로 두고 그 객체를 복제하여 전달받은 서버를 Secondary로 두는 방식입니다. 즉, 백업용 서버라고 볼 수 있습니다. 그리고 나서 나머지 서버들은 Key에 해당하는 Session ID만을 저장함으로써 이전 방법보단 메모리를 아낄 수 있습니다. 다만, 이 방식도 Session ID만을 갖고 있는 서버는 세션 객체를 갖고 있는 Primary 서버에게 요청을 해야한다는 단점이 있습니다.

참고 자료

undefined

Copyright 2023. all rights reserved by Jayden