Cookie / Session

1Hoit·2023년 3월 10일
0

들어가기전

쿠키, 세션 사용하는 이유

  • 사용자가 로그인을 하고 다른 페이지로 이동을 했을 때, 그 로그인을 유지하기 위해서,
  • 같은 사이트를 방문 시, 여러 개의 이미지들을 불필요한 로드를 없애기 위해서 등 여러가지 이유가 있다.
  • 세밀하게 보면 HTTP와 관련이 있다
    HTTP의 특징과 쿠키와 세션을 사용하는 이유
    • HTTP 프로토콜의 특징이자 약점을 보완하기 위해서 사용한다.
    • HTTP 프로토콜 환경에서 서버는 클라이언트가 누구인지 확인해야한다. 그 이유는 HTTP 프로토콜이 connectionless, stateless한 특성이 있기 때문이다.
    • 예를 들어, 쿠키와 세션을 사용하지 않으면 쇼핑몰에서 옷을 구매하려고 로그인을 했음에도, 페이지를 이동할 때 마다 계속 로그인을 해야 한다.
      쿠키와 세션을 사용했을 경우, 한 번 로그인을 하면 어떠한 방식에 의해서 그 사용자에 대한 인증을 유지하게 된다.

어떤 웹사이트에 접속시, 서버가 클라이언트(브라우저) 로컬에 전달하는 기와 값이 들어있는 작은 데이터 파일
즉, 서버가 웹 브라우저에 정보를 저장하고 불러올 수 있는 수단

  • Response Header에 Set-Cookie 속성을 사용하면 클라이언트에 쿠키를 만들 수 있다.
  • 서버가 쿠키를 브라우저에 저장해주고 해당 도메인에 대해 쿠키가 존재하면,
    웹 브라우저는 도메인(서버)에게 요청(Request)시에 Request Header를 넣어서 자동으로 서버에 전송한다.
  • 쿠키는 서버에서 클라이언트에 영속성있는 데이터를 저장하는 방법이다.
    서버는 클라이언트의 쿠키를 이용하여 데이터를 가져올 수 있다.

쿠키의 동작 방식

  1. 클라이언트가 페이지를 요청
  2. 서버에서 쿠키를 생성
  3. HTTP 헤더에 쿠키를 포함 시켜 응답
  4. 브라우저가 종료되어도 쿠키 만료 기간이 있다면 클라이언트에서 보관하고 있음
  5. 같은 요청을 할 경우 HTTP 헤더에 쿠키를 함께 보냄
  6. 서버에서 쿠키를 읽어 이전 상태 정보를 변경 할 필요가 있을 때 쿠키를 업데이트 하여 변경된 쿠키를 HTTP 헤더에 포함시켜 응답

쿠키가 매 요청시 마다 자동으로 서버에 전달되는데
이를 바탕으로 사용자 선호, 테마 , 로그인 유지 등 장시간 보존해야하는 정보 저장에 적합하다.

  • 방문 사이트에서 로그인 시, "아이디와 비밀번호를 저장하시겠습니까?"
  • 쇼핑몰의 장바구니 기능
  • 자동로그인, 팝업에서 "오늘 더 이상 이 창을 보지 않음" 체크

서버가 클라이언트에 특정한 데이터를 저장할 수 있다.

  • 앞서 언급한 것처럼 서버는 쿠키를 이용하여 데이터를 저장하고 이 데이터를 다시 불러와 사용할 수 있다.
    하지만 데이터를 저장한 이후 아무 때나 데이터를 가져올 수는 없다.
    데이터를 저장한 이후 특정 조건들이 만족되어야 다시 가져올 수 있기 때문이다.

조건들은 아래 코드처럼 http 헤더를 사용해 쿠키 옵션으로 표현할 수 있습니다.

Set-Cookie HTTP 응답 헤더는 서버에서 사용자 브라우저에 쿠키를 전송하기 위해 사용한다.

'Set-Cookie':[
            'cookie=yummy', 
            'Secure=Secure; Secure',
            'HttpOnly=HttpOnly; HttpOnly',
            'Path=Path; Path=/cookie',
            'Doamin=Domain; Domain=codestates.com'
        ]

쿠키 옵션 종류

  1. Domain
    도메인이라는 것은 서버에 접속할 수 있는 이름이다.
    요청해야 할 URL이 http://www.localhost.com:3000/users/login 이라 하면 여기에서 Domain은 localhost.com 이다.
  • 쿠키 옵션에서 도메인 정보가 존재한다면 클라이언트에서는 쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다.
  1. Path
    Path는 세부 경로로써 서버가 라우팅할 때 사용하는 경로를 의미한다.
    요청해야 하는 URL이 http://www.localhost.com:3000/users/login 인 경우라면 여기에서 Path는 /users/login이 됩니다.
    이를 명시하지 않으면 기본적으로 / 으로 설정되어 있다.
  • Path 옵션의 특징은 설정된 경로를 포함하는 하위 경로로 요청을 하더라도 쿠키를 서버에 전송할 수 있다. 즉 Path가 /users로 설정되어 있고, 요청하는 세부 경로가 /users/code 인 경우라면 쿠키 전송이 가능하다.
  1. MaxAge or Expires
    쿠키가 유효한 기간을 정하는 옵션이다.
    만약 쿠키가 영원히 남아있다면 그만큼 탈취되기도 쉬워지기 때문에 이러한 유효기간을 설정하는 것이 보안 측면에서 중요하다.
  • MaxAge는 쿠키가 유효한 시간을 초 단위로 설정하는 옵션이다.

  • Expires는 MaxAge와 비슷하지만 언제까지 쿠키가 유효한지 심판의 날을 지정할 수 있다. 이때 옵션의 값은 클라이언트의 시간을 기준으로 한다.
    이후 지정된 시간, 날짜를 초과하게 되면 쿠키는 자동으로 파괴된다.

  • 쿠키는 위 옵션의 여부에 따라 세션 쿠키(Session Cookie)와 영속성 쿠키(Persistent Cookie)로 나눠진다.

    • 세션 쿠키: MaxAge 또는 Expires 옵션이 없는 쿠키로, 브라우저가 실행 중일 때 사용할 수 있는 임시 쿠키이다. 브라우저를 종료하면 해당 쿠키는 삭제된다.
    • 영속성 쿠키: 브라우저의 종료 여부와 상관없이 MaxAge 또는 Expires에 지정된 유효시간만큼 사용가능한 쿠키이다.
  1. Secure
    사용하는 프로토콜에 따른 쿠키의 전송 여부를 결정하는 옵션이다.
    Secure 옵션이 true로 설정된 경우 HTTPS를 이용하는 경우에만 쿠키를 전송할 수 있다.
  • Secure 옵션이 없다면 프로토콜에 상관없이 http://www.codestates.com 또는 https://www.codestates.com에 모두 쿠키를 전송할 수 있습니다.
  • 단, 도메인이 localhost 인 경우에는 HTTPS가 아니여도 쿠키 전송이 가능하다.
  1. HttpOnly
    자바스크립트로 브라우저의 쿠키에 접근이 가능한지 여부를 결정한다.
    옵션이 true로 설정된 경우, 자바스크립트로 쿠키에 접근이 불가하다.
  • 옵션을 명시하지 않는 경우에는 기본적으로 false로 지정된다.
  • 옵션이 false인 경우 document.cookie를 이용해 자바스크립트로 쿠키에 접근할 수 있으므로 쿠키가 탈취될 위험이 있다.
  1. SameSite
    Cross-Origin (CORS)요청을 받은 경우, 요청에서 사용한 메소드(e.g. GET, POST, PUT, PATCH …)와 해당 옵션의 조합을 기준으로 서버의 쿠키 전송 여부를 결정하게 된다.

    사용 가능한 옵션은 다음과 같다.

  • Lax: Cross-Origin 요청이라면 GET 메소드에 대해서만 쿠키를 전송할 수 있다.
  • Strict: 가장 엄격한 옵션으로, Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있다.
  • None: Cross-Origin에 대해 가장 관대한 옵션으로 항상 쿠키를 보내줄 수 있다.
    다만 쿠키 옵션 중 Secure 옵션이 필요합니다.
    이때 same-site는 요청을 보낸 Origin과 서버의 도메인, 프로토콜, 포트가 같은 경우를 말하며 이 중 하나라도 다르다면 Cross-Origin으로 구분된다.

Session

  • 세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리 세션은 서버 측에서 관리한다.
  • 서버에서는 클라이언트를 구분하기 위해 세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지한다.
    • 물론 접속 시간에 제한을 두어 일정 시간 응답이 없다면 정보가 유지되지 않게 설정이 가능 하다.
  • 사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만, 사용자가 많아질수록 서버 메모리를 많이 차지하게 된다.
    • 동접자 수가 많은 웹 사이트인 경우 서버에 과부하를 주게 되므로 성능 저하의 요인이 된다.
  • 클라이언트가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는 데 이것이 세션ID다.

세션의 동작 방식

  1. 클라이언트가 서버에 접속 시 세션 ID를 발급 받음
    사용자가 만일 정확한 아이디와 비밀번호를 입력했다면, 서버는 인증(Authentication)에 성공했다고 판단한다.

    • 이에 따라 다음번 인증을 필요로 하는 작업 (장바구니 물품추가등)에서 또 다시 로그인을 할 필요가 없어진다.
    • 인증에 따라 리소스의 접근 권한(Authorization)이 달라진다.
    • 서버: 사용자가 인증에 성공했음을 알고 있어야 한다
    • 클라이언트: 인증 성공을 증명할 수단을 갖고 있어야 한다

      잠시 용어 정리 및 상세과정 살펴보기

    • 사용자가 인증에 성공한 상태는 세션이라고 부른다.
    • 서버는 일종의 저장소에 세션을 저장한다. (그림에서 2번)
      주로 in-memory(자바스크립트 객체), 또는 세션 스토어(redis 등과 같은 트랜잭션이 빠른 DB)에 저장한.
    • 세션이 만들어지면, 각 세션을 구분할 수 있는 세션 아이디도 만들어지는데(그림에서 3번), 보통 클라이언트에 세션 성공을 증명할 수단으로써 쿠키에 세션 아이디를 담아서 전달한다. (그림에서 4번)
    • 웹사이트에서 로그인을 유지하기 위한 수단으로 쿠키를 사용한다.
      쿠키에는 서버에서 발급한 세션 아이디를 저장한다.
  2. 클라이언트는 세션 ID에 대해 쿠키를 사용해서 저장하고 가지고 있다.

  3. 클라이언트는 서버에 요청할 때, 이 쿠키의 세션 ID를 서버에 전달해서 사용한다.

  4. 서버는 세션 ID를 전달 받아서 별다른 작업없이 세션 ID로 세션에 있는 클라언트 정보를 가져온다.

  5. 클라이언트 정보를 가지고 서버 요청을 처리하여 클라이언트에게 응답한다.

  • 만약 쿠키에 세션 아이디 정보가 없는 경우, 서버는 해당 요청이 인증되지 않았음을 알려준다.

잠시 정리
세션 아이디가 담긴 쿠키는 클라이언트에 저장되어 있으며, 서버는 세션을 저장하고 있다.
그리고 서버는 그저 세션 아이디로만 인증 여부를 판단한다.
그러므로 로그아웃은 다음 두 가지 작업을 해야 한다.

  • 서버: 세션 정보를 삭제해야 함.
  • 클라이언트: 쿠키를 갱신하거나 삭제해야 함.
  • 클라이언트에서 세션 정보를 없애기 위해서는 res.cookie로 쿠키의 값을 무효한 값으로 갱신하거나, res.clearCookie로 쿠키를 삭제해버리면 된다.

세션의 사용 예

로그인 같이 보안상 중요한 작업을 수행할 때 사용

세션의 특징

  • 서바가 각 클라이언트에게 고유한(암호화된) ID를 부여
  • 중요 데이터는 서버에서 관리
  • 세션 ID로 클라이언트를 구분해서 클라이언트의 요구에 맞는 서비스를 제공
  • 보안 면에서 쿠키보다 우수
  • 사용자가 많아질수록 서버 메모리를 많이 차지하게 됨

쿠키와 세션의 차이

쿠키와 세션은 비슷한 역할을 하며, 동작원리도 비슷하다.
그 이유는 세션도 결국 쿠키를 사용하기 때문이다.

  • 가장 큰 차이점: 사용자의 정보가 저장되는 위치
    쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용한다.

  • 보안: 세션이 더 우수하며, 요청 속도는 쿠키가 세션보다 더 빠르다.
    그 이유는 세션은 서버의 처리가 필요하기 때문입니다.
    • 쿠키는 클라이언트 로컬에 저장되기 때문에 변질되거나 request에서 스니핑 당할 우려가 있어서 보안에 취약하지만
      세션은 쿠키를 이용해서 sessionid 만 저장하고 그것으로 구분해서 서버에서 처리하기 때문에 비교적 보안성이 좋다.

  • 라이프 사이클:
    • 쿠키도 만료시간이 있지만 파일로 저장되기 때문에 브라우저를 종료해도 계속해서 정보가 남아 있을 수 있다. 또한 만료기간을 넉넉하게 잡아두면 쿠키삭제를 할 때 까지 유지될 수도 있다.
    • 세션도 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제된다.
      예를 들어, 크롬에서 다른 탭을 사용해도 세션은 공유된다.
      다른 브라우저를 사용하게 되면 다른 세션을 사용할 수 있다.

  • 속도: 쿠키에 정보가 있기 때문에 서버에 요청시 속도가 빠르고 세션은 정보가 서버에 있기 때문에 처리가 요구되어 비교적 느린 속도를 가진다.

마무리

세션은 사용자의 수 만큼 서버 메모리를 차지하기 때문에,
최근에는 이런 문제들을 보완한 토큰 기반의 인증방식을 사용하는 추세이다.
그 중 JWT( JSON Web Token )라는 것이 있다.
이는 다음 포스팅에서 알아보자.

profile
프론트엔드 개발자를 꿈꾸는 원호잇!

0개의 댓글