[정리: 네트워크] 쿠키와 세션, Stateless

Stateless

Stateless

  • 각 HTTP 요청과 응답이 독립적인 특성을 의미한다. 서버는 이전에 수행한 요청과 그 결과에 대한 정보를 저장하지 않는다. - 따라서 이전의 상태 정보가 없으므로 서버는 이전에 클라이언트가 누구 였는지, 무엇을 했는지 알 수 없다. 이를 보완하기 위해 쿠키와 세션과 같은 상태 정보를 유지하는 방안을 사용한다. - 왜냐하면 실제 서비스에서는 상태 정보를 유지해야 하는 경우가 많기 때문이다. 예를 들어 사용자 인증과 같은 경우, 인증된 사용자라는 상태를 계속 유지해야 그 기능을 제공할 수 있음

그럼에도 불구하고 Stateless 하게 구현한 이유

  • 서버가 클라이언트의 상태를 추적하거나 저장할 필요가 없으므로, 구현이 단순
  • 각 요청이 독립적으로 처리되므로, 다수의 서버에 요청을 분산시키는 로드 밸런싱이 훨씬 쉬워짐
  • 각 요청이 독립적으로 처리되므로 확장성이 좋아짐
  • 각 요청과 응답이 독립적이므로, 응답을 캐시에 저장하고 재사용하는 것이 가능

Stateless과 RESTful

  • REST 아키텍처도 Stateless를 기본 원칙 중 하나로 삼고 있다.

    • RESTful 웹 서비스에서 Stateless과 특성은 각 API 요청이 서로 독립적이라는 것을 의미한다.
  • 모든 요청에 필요한 정보는 해당 요청 자체에 모두 담겨 있어야 하며, 서버는 클라이언트의 상태 정보를 저장해서는 안된다.

    • 즉, RESTful API 호출 하나는 그 자체로 완전하며 이전 요청이나 이후 요청에 의존하지 않아야 한다.
  • RESTful 웹 서비스에서 인증을 구현하는 방법 - 일반적으로 OAuth, JWT와 같은 토큰 기반의 인증방식을 사용한다. 이를 사용하면 토큰은 각 API 요청에 포함되어 전송되며, 서버는 이 토큰만을 보고 요청의 유효성을 판단하게 된다.
  • (보충) 토큰과 세션ID의 차이 - 토큰 자체가 모든 필요한 정보를 가지고 잇다. 이 정보는 서버에서 미리 정의된 비밀 키로 서명되어 있기 때문에 토큰만 보고 누구인지 인증이 가능하다. - 따라서 서버가 클라이언트의 상태를 저장할 필요가 없다.

쿠키와 세션의

  • HTTP는 Stateless한 특성을 가지고 있다. 따라서 통신에서 Request와 Response가 독립적이며, 이전 요청과 이후 요청 사이에 상태를 유지하지는 않는다. 이러한 Stateless한 특성 때문에 상태를 유지하기 위한 메커니즘으로 HTTP 프로토콜의 일부로 쿠키가 도입되었고, 서버 측에서는 세션을 구현하게 되었다.
  • 쿠키는 HTTP 프로토콜의 일부로, 앞서 말했듯이 HTTP에서 상태를 보장하기 위해 나온 개념이라고 할 수 있다. HTTP 로 통신을 할 때, 쿠키는 클라이언트 측에 저장되며 (브라우저의 일종의 데이터베이스가 있는 것으로 알고 있음) 저장된 쿠키는 매 통신마다 붙어나갈 수 있다. 또한 쿠키의 저장의 경우 브라우저에서 직접 저장할 수도 있고 서버 측에서 통신에 set-cookie 헤더를 통하여 브라우저에 직접 설정해줄 수도 있다.
  • 그러나 세션의 경우, HTTP 프로토콜의 일부는 아니고 HTTP의 Stateless를 극복하기 위한 서버 측의 구현이다. 따라서 세션의 데이터는 서버 메모리에 저장된다. 이러한 세션에 접근하기 위해서는 세션 ID가 필요한데 일반적으로 세션 ID를 쿠키에 저장을 한다.
  • 조금 더 자세하게 셜명하자면 사용자가 인증되면 서버는 고유한 세션 ID를 생성하고, 이를 세션 저장소에 보관한다. 이후 쿠키를 통해 클라이언트에 세션 ID를 전송하며 이 ID로 클라이언트를 식별할 수 있다.
  • 간단하게 정리하면, 쿠키는 클라이언트 측에, 세션은 서버 측에 데이터를 저장한다. 쿠키는 상태 정보를 클라이언트-서버 간에 전송하는 역할을 하고, 세션은 그 상태 정보를 서버 내에서 실제로 관리하는 역할을 한다.

쿠키의 보안 이슈

  • HTTP의 경우, 암호화 되지 않고 통신이 진행되기 때문에 쿠키에 중요한 데이터를 저장하면 탈취당할 수 있음.
  • 따라서 쿠키를 전달할 때 HTTPS를 사용하는 것이 권장되고, 이를 강제하기 위해서 Chrome 버전 80부터 쿠키에 SameSite 옵션이 강제되었음. 이 옵션에 Strict 값을 사용하려면 쿠키가 동일한 사이트 내의 요청으로만 전송되고, 크로스 도메인 사이에서 사용하려면 Lax를 사용해야하는데 Lax를 사용하기 위해서는 반드시 HTTPS에서만 동작하는 Secure Cookie 옵션을 사용해야 한다.

세션 방식의 로그인 과정

  • 사용자가 클라이언트에서 로그인을 하면, 인증 정보를 body에 담아 서버로 request를 보낸다.
  • 서버는 이 body를 통하여, 사용자를 구별할 수 있는 식별자인 세션 ID를 생성한다. 그리고, 이 세션 ID를 서버의 세션 저장소에 저장한다.
  • 생성한 세션 ID를 사용자의 웹 브라우저에 전달한다. 이 때, response 헤더에 Set-cookie를 이용하여, 클라이언트에 직접 쿠키를 설정할 수 있다.
  • 이를 통해, 웹 브라우저는 이 세션 ID를 쿠키에 저장한다.
  • 쿠키가 저장되면 이 후 HTTP의 모든 요청에 쿠키가 붙어서 통신할 수 있다. 이 정보를 통해 인증에 대한 요청이 처리될 수 있다.
  • 사용자가 로그아웃하거나, 서버에서 지정한 세션 기한이 지나면 세션이 만료된다. 즉, 세션 저장소에서 해당 ID를 삭제하므로 이 기간이 지나면 사용자는 재로그인 해야 한다.

단점

  • 그러나 세션 방식을 사용하면 상태를 유지하기 위해 서버 측에 데이터를 저장해야 한다. 이는 RestFul에서 “모든 요청에 필요한 정보는 해당 요청 자체에 모두 담겨 있어야 하며, 서버는 클라이언트의 상태 정보를 저장해서는 안된다.”를 위반한다. 따라서 Restful의 장점인 확장성 측면에서 불리하게 적용될 수 있다. - 서버의 메모리를 사용한다는 것은 확장성에 제한을 주는 일이다.
  • 따라서, 최근에는 Restful 을 지키면서 확장성이 좋은 토큰 (JWT, OAuth) 을 이용한 인증을 널리 사용하고 있다. (이 경우, 각 요청에 전달되는 토큰의 값 만으로 사용자 인증 정보를 확인할 수 있다.)

Written by@AllSilver
철학적인 개발자를 꿈꿉니다.

GitHub