개인공부/TIL(Today I Learned)

TIL 86일차_쿠키와 세션

soon327 2021. 4. 14. 22:22

인증(authentication)을 공부하면서
배우게 되는 쿠키와 세션에 대해 정리해봤다.
특히 express-session 라이브러리를 사용하여 쿠키설정을 하는 부분은
까먹을게 분명하니까 꼭 적어놔야지!

쿠키

쿠키란???
쿠키는 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 조각이다.
브라우저는 그 데이터 조각들을 저장해 놓았다가,
동일한 서버에 재 요청 할 때, 저장된 데이터 조각(쿠키)를 함께 전송한다.
쿠키는 주로 두 요청이 동일한 브라우저에서 들어왔는지를 판단할 때 사용한다.
쿠키는 http의 무상태성을 상태를 가질 수 있게 만들어주기때문에,
사용자의 로그인 상태를 유지하는 등에 쓰인다.

쿠키의 동작 방식

서버에서 HTTP요청을 수신할 때,
서버는 응답과 함께 Set-Cookie 헤더를 전송할 수 있다.
이 서버헤더는 클라이언트에게 쿠키를 저장해!! 라고 명령하는 역할을 한다.

Set-Cookie의 기본 구조는 다음과 같다.

Set-Cookie: <cookie name>=<cookie value>

예를 들어 다음과 같이 Set-Cookie HTTP 응답 헤더가 서버로부터 사용자 에이전트로 전송되었다면,

Set-Cookie: test_cookie=cheeze
Set-Cookie: yummy_cookie=choco

이 서버 헤더는 클라이언트에게 쿠키를 저장하라고 전달한다.
그러면 브라우저는 서버에 요청을 보낼 때, Cookie 헤더를 사용하여
아래와 같이 이전에 저장했던 모든 쿠키들을 같이 회신한다.

GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie:test_cookie=cheeze; yummy_cookie=choco

쿠키의 동작방식을 정리하면 다음과 같다.

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

세션 (Session)

세션이란???
세션은 쿠키를 기반하고 있지만, 사용자 정보 파일을 브라우저에 저장하는 쿠키와 달리
세션은 서버측에서 관리한다.

서버에서는 클라이언트를 구분하기 위해 세션ID를 부여하며, 설정에 따라 인증상태를 유지한다.
클라이언트가 Request를 보내면, 해당 서버의 엔진이 클라이언트에게 유일한 ID를 부여하는 데 이것이 세션ID다.

사용자에 대한 정보를 서버에 두기 때문에 쿠키보다 보안에 좋지만,
사용자가 많아질수록 서버 메모리를 많이 차지하게 된다.
따라서 최근에는 이런문제들을 보완한 토큰 기반의 인증방식을 사용한다.

쿠키와 세션의 차이

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

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

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

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

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

쿠키/세션과 캐시는 다르다.

캐시는 이미지나 css,js파일 등을 브라우저나 서버 앞단에 저장해놓고 사용하는 것이다.
한번 캐시에 저장되면 브라우저를 참고하기 때문에 서버에서 변경이 되어도 사용자는 변경되지 않게 보일 수 있는데,
이런 부분을 캐시를 지워주거나 서버에서 클라이언트로 응답을 보낼 때 header에 캐시 만료시간을 명시하는 방법등을 이용할 수 있다.

express-session 라이브러리를 이용한 쿠키 설정

express-session은 세션을 위한 미들웨어로, Express에서 세션을 다룰 수 있는 공간을 보다 쉽게 만들어준다.
또한 필요한 경우 세션 아이디를 쿠키에 저장하고, 해당 세션 아이디에 종속되는 고유한 세션 객체를 서버 메모리에 저장한다.
이때 세션 객체는 서로 독립적인 객체이므로 각각 다른 데이터를 저장할 수 있습니다.
req.session이 바로 세션 객체이며 req.session은 세션 객체에 세션 데이터를 저장거나 불러오기 위해 사용한다.

아래처럼 req.session라는 객체모양의 세션 스토어를 생성해주는 동시에
쿠키설정을 해줄 수 있다.

app.use(
  session({
    secret: '@secretcode',
    resave: false,
    saveUninitialized: true,
    cookie: {
      domain: 'localhost',
      path: '/',
      maxAge: 24 * 6 * 60 * 10000,
      sameSite: 'None',
      httpOnly: true,
      secure: true,
    },
  })
);

쿠키 설정 옵션들을 살펴보자!

  1. Domain

쿠키옵션에서 도메인은 포트 및 서브 도메인정보, 세부경로를 포함하지 않는다.
요청해야할 URL이 http://www.localhost.com:3000/users/login 이라면,
Domain은 localhost.com이 된다.
만약 쿠키 옵션에서 도메인 정보가 존재한다면 클라이언트에서는
쿠키의 도메인 옵션과 서버의 도메인이 일치해야만 쿠키를 전송할 수 있다.

  1. Path

세부 경로는 서버가 라우팅할 때 사용하는 경로이다.
만약 요청해야 하는 URL이 http://www.localhost.com:3000/users/login 인 경우라면
여기에서 Path, 세부 경로는 /users/login이 된다.

  1. MaxAge , Expires

쿠키가 유효한 기간을 정하는 옵션이다.
MaxAge는 앞으로 몇 초 동안 쿠키가 유효한지 설정하는 옵션이며,
Expires 은 MaxAge와 비슷하지만 언제까지 유효한지 Date를 지정한다.

이후 지정된 시간, 날짜를 초과하게 되면 쿠키는 자동으로 파괴됩니다.
하지만 두 옵션이 모두 지정되지 않는 경우에는 브라우저의 탭을 닫아야만 쿠키가 제거된다.

  1. SameSite

Cross-Origin 요청을 받은 경우 요청에서 사용한 메소드와 해당 옵션의 조합으로 서버의 쿠키 전송 여부를 결정하게 된다.

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

  • Lax :Cross-Origin 요청이면 'GET' 메소드에 대해서만 쿠키를 전송할 수 있다.
  • Strict : Cross-Origin이 아닌 same-site 인 경우에만 쿠키를 전송 할 수 있다.
  • None: 항상 쿠키를 보내줄 수 있습니다. 다만 쿠키 옵션 중 Secure 옵션이 필요하다.

이때 'same-site'는 요청을 보낸 Origin과 서버의 도메인이 같은 경우를 말합니다.

  1. HttpOnly

자바스크립트에서 브라우저의 쿠키에 접근 여부를 결정한다.
만약 해당 옵션이 true로 설정된 경우, 자바스크립트에서는 쿠키에 접근이 불가하다.

명시되지 않는 경우 기본으로 false로 지정되어 있다.
만약 이 옵션이 false인 경우 자바스크립트에서 쿠키에 접근이 가능하므로 'XSS' 공격에 취약하다.

옵션명때문에 오해할 수 있지만, Https 설정과는 상관없다.

  1. Secure

쿠키를 전송해야 할 때 사용하는 프로토콜에 따른 쿠키전송 여부를 결정한다.
만약 해당 옵션이 true로 설정된 경우, 'HTTPS' 프로토콜을 이용하여 통신하는 경우에만 쿠키를 전송 할 수 있다.


이러한 옵션들을 지정한 다음 서버에서 클라이언트로 쿠키를 처음 전송하게 된다면
헤더에 Set-Cookie라는 프로퍼티에 쿠키를 담아 쿠키를 전송하게 된다.

이후 클라이언트 혹은 서버에서 쿠키를 전송해야 한다면 클라이언트는
헤더에 Cookie라는 프로퍼티에 쿠키를 담아 서버에 쿠키를 전송하게 된다.


Reference

MDN_HTTP쿠키
라이언곰돌이푸