[Security] 쿠키(Cookie)와 세션(Session)

jiveloper·2024년 2월 25일
0

Security

목록 보기
2/3
post-thumbnail
post-custom-banner

0. 들어가며

이전 시간 (약 1년전...)에는 인증(Authentication)과 인가(Authorization)에 대해 알아보았습니다.

(작년에 인증과 인가, 세션과 토큰에 대해서 공부를 하였는데, 약 1년만에 이어서 포스팅을 하네요...🥲🥲 1년만이지만 열심히 포스팅해보겠습니다...!!!!)


저번 시간에 배운 것을 한 번 더 복습해보겠습니다.

HTTP는 비상태성의 특징을 가지며, 인증된 사용자에게 필요한 기능을 인가하여야한다.

우리는 보통 웹사이트를 이용할 때, 로그인을 한 후에 서비스를 이용하곤 합니다. 로그인을 하면 회원 사용자만이 할 수 있는 기능(ex. 게시판 글 쓰기, 댓글 달기 등)을 할 수 있습니다.

  • 로그인 : 클라이언트가 서버에게, "사용자"가 누구임을 밝히는 과정 (인증)
  • 로그인 성공 : 서버가 클라이언트에게 사용자의 "역할"을 제공 (글 쓰기, 댓글 등 기능 이용 가능하도록 인가)

이런식으로 HTTP에서 사용자를 인증 및 인가 하는 방법은 다양합니다.
오늘은 그 중에서도 쿠키와 세션을 이용한 인증 및 인가 방식에 대해 알아보겠습니다.



1. 쿠키(Cookie)란?

쿠키는 기본적으로 HTTP 통신을 기반으로 하며 브라우저에서 널리 사용되고 있습니다.

쿠키(Cookie)란?
서버가 어떤 데이터를 브라우저 측에 저장한 후 다시 그 데이터를 받아오는 기술, 또는 그 데이터 자체

우리는 저번 시간에 HTTP는 비상태성이기 때문에 매요청마다 사용자를 알 수 없다고 배웠습니다. 이러한 HTTP 환경에서 매번 로그인을 하지 않고 서비스를 이용하려면, 매 요청마다 사용자가 누구인지 알려줄 필요가 있겠습니다.

바로 이 쿠키가 그 역할을 해주는데요, 브라우저가 서버에게 매 요청마다 사용자를 식별할 수 있는 값을 쿠키에 담아 보내줌으로써 사용자가 누구인지 알려줄 수 있게 됩니다.

그렇다면 이 쿠키는 언제 최초로 생성될까요? 사용자 인증을 해야 그에 따른 인가를 하기 때문에 최초에 사용자 인증을 할 수 있는 로그인 시점에 생성됩니다.


2. 쿠키의 흐름

1. 쿠키 최초 생성

로그인을 통해 사용자 인증을 하면, 서버는 브라우저에게 최초로 쿠키 값을 제공합니다. 그 후, 브라우저는 서버로부터 받은 쿠키 값을 저장합니다. 😋 🍪

아래와 같은 형태로 각 쿠키를 HTTP 메세지의 Set-Cookie 헤더에 실어서 응답합니다.

1) 단일 쿠키🍪만 보낼 경우

Set-Cookie: <🍪 이름>=<🍪 >

2) 여러 쿠키🍪🍪를 보낼 경우

Set-Cookie: <🍪 이름>=<🍪 >
Set-Cookie: <🍪 이름>=<🍪 >

2. 쿠키의 역할

이제 브라우저는 사용자가 같은 도메인에 머무는 한, 어디를 방문하든 매번 같은 쿠키를 돌려줌으로써 사용자가 누구인지 알려주게 됩니다. 브라우저는 일정 시간동안 계속해서 서버로 쿠키를 돌려 보내줍니다.

GET /index
Host: www.jiveloper.com
Cookie: a=1; b=2
GET /about
Host: www.jiveloper.com
Cookie: a=1; b=2

3. 쿠키의 정보

쿠키가 담긴 HTTP 메세지의 Set-Cookie 헤더에 대해 자세히 알아봅시다.

1. 유효기간

위에서 브라우저는 일정 시간동안 계속해서 서버로 쿠키를 돌려 보낸다고 설명드렸는데요, 브라우저가 쿠키를 얼마나 오래동안 돌려 보내야하는지는 서버가 맨 처음 쿠키를 보낼 때 결정을 하며, Set-Cookie 응답 헤더를 통해 명시되어야 합니다.

  • 유효 기간이 명시되어 있는 영속 쿠키(permanent cookie)

쿠키를 특정 기간이나 특정 시점까지 유효하게 지정하려면 Set-Cookie 응답 헤더에 Expires 속성이나 Max-Age를 사용할 수 있습니다. expires 속성과 max-age 속성이 둘 다 있을 경우 max-age 속성이 우선합니다.

참고로 브라우저에 저장해두었던 쿠키를 즉시 만료하고 싶을 때는 max-age 속성을 0으로 설정해주면 됩니다.

Set-Cookie: <🍪 이름>=<🍪 >; expires=2024-02-27T13:09:09.191Z
Set-Cookie: <🍪 이름>=<🍪 >; max-age=1709000923994
  • 유효 기간이 별도로 명시되지 않는 세션 쿠키(session cookie)
    쿠키가 브라우저의 세션이 종료될 때 함께 만료됩니다. 즉, 브라우저의 탭이나 윈도우를 닫으면 서버가 보냈던 쿠키는 모두 만료되어 브라우저는 더 이상 해당 쿠키를 서버에 돌려 보내지 않습니다.

2. 적용 범위

브라우저가 기본적으로 쿠키를 보낸 서버가 속한 도메인으로만 쿠키를 되돌려 보내지만 특정 URL을 방문할 때 해당 쿠키를 보낼 수도 있습니다.

  • 쿠키 확장
    Set-Cookie 응답 헤더에 Domain 속성을 명시하면, 해당 도메인까지 포함되도록 쿠키의 범위가 확장됩니다.

    Set-Cookie: <🍪 이름>=<🍪 >; domain='.jieonist.com'

    🤓: 예를 들어, www.jiveloper.com으로 부터 받은 쿠키를, www.jieonist.com으로 보낼 수 있습니다. 이렇게 되면 www.jiveloper.com과 www.jieonist.com이 쿠키를 공유할 수 있게 됩니다.

  • 쿠키 축소
    Set-Cookie 응답 헤더에 path 속성을 명시하면 쿠키의 범위를 해당 도메인의 특정 경로로 쿠키의 범위를 축소시킬 수 있습니다.

    Set-Cookie: <🍪 이름>=<🍪 >; path=/user

    🤓: 예를 들어, path 속성이 /user라고 설정되어 있는 쿠키는, 브라우저가 /users를 포함한 하위 경로로 요청을 할 때만 서버로 돌려 보냅니다.

3. 보안 속성

반드시 쿠키를 사용해야 하는 상황이라면 가급적 아래와 같은 보안 속성을 사용하시기를 권장드립니다.

  • Secure
    Set-Cookie 응답 헤더에 이 속성이 명시된 쿠키는 브라우저가 https 프로토콜 상에서만 서버로 돌려 보냅니다. 네트워크 상에서 탈취되었을 때 문제가 될 수 있는 쿠키를 상대로 쓰면 유용할 것입니다.

    Set-Cookie: <🍪 이름>=<🍪 >; secure
  • HttpOnly
    Set-Cookie 응답 헤더에 이 속성이 명시된 쿠키는 서드 파티(third party) 자바스크립트 코드가 쿠키에 접근하는 것을 제한할 수 있습니다.

    Set-Cookie: <🍪 이름>=<🍪 >; HttpOnly

4. 쿠키의 한계

쿠키는 브라우저에 저장을 하는 것이기 때문에, 사용자가 쉽게 쿠키를 확인할 수 있다고 말씀드렸습니다. 그렇기 때문에, 사용자의 노출이 쉬워 갖가지 이슈를 가집니다.

따라서 쿠키를 사용할 때는 아래와 같은 쿠키의 한계점들을 잘 인지하고 사용하는 것이 중요합니다. 🤓

1. 쿠키는 유실되기 쉽습니다.

당장 크롬만 봤을 때, 인터넷 사용 삭제 기록 란에 쿠키 데이터가 있는 것을 확인하실 수 있습니다. 쿠키를 어렵지 않게 삭제할 수 있기 때문에, 중요한 데이터는 쿠키를 사용해서 브라우저에 저장하시면 안 됩니다!

2. 쿠키는 변조되기 쉽습니다.

브라우저의 개발자 도구를 사용하면 각 웹사이트 별로 현재 어떤 쿠키가 저장되어 있는지 한 눈에 파악할 수 있으며 쿠키를 손쉽게 변경할 수 있습니다. 이를 통해 서버가 브라우저로 보낸 쿠키와 전혀 다른 쿠키를 서버에 돌려 보낼 수도 있으며, 심지어 서버가 저장한 적이 없는 새로운 쿠키를 만들어서 서버에 보낼 수도 있습니다.


2. 세션 (Session)

세션이란 단어는 개발자가 아니어도 충분히 자주 접해보았을 단어라고 생각합니다. 세션이라는 단어가 무슨 뜻인지 알아봅시다.

세션(Session)이란?
사용자가 인증에 성공하여 서버와 클라이언트 간의 상호작용을 위해 일시적인 시간동안 유지되는 값.

비상태성인 HTTP 환경에서 이 세션 값이 있는 쿠키를 저장하고, 매 요청마다 세션 값을 쿠키에 담아 데이터를 요청함으로써 사용자가 누구인지 인증 할 수 있게 됩니다.

그렇다면 인증된 사용자의 정보를 어디에 어떻게 저장할까요?

1. 동작 과정

서버와 클라이언트간의 세션을 통한 통신 과정을 조금 더 자세히 알아보겠습니다.

1. 사용자 인증하기! (feat. 세션 생성 과정)

저번 시간에는 인증에 대한 정의와 인증은 로그인을 통해 이루어진다는 것을 배웠습니다. 어떻게 인증이 되는지 그림을 통해 알아봅시다.

  1. 브라우저에서 사용자는 아이디(id) 및 비밀번호(pw)를 입력합니다.
  2. 브라우저는 서버로 사용자가 입력한 아이디와 비밀번호를 전달합니다.
  3. 서버는 전달 받은 아이디와 비밀번호가 일치하는 유저를 조회합니다.
  4. (유저 데이터가 유효하다면) 유저 데이터를 세션 데이터베이스에 전달합니다.
    (* 만약 유저 데이터가 유효하지 않다면 바로 8번으로 넘어가서 로그인에 실패했다는 에러 메세지를 보낼 것입니다. (쿠키 없이!!))
  5. 세션 데이터베이스는 세션 아이디를 생성합니다.

  1. 세션 데이터베이스는 서버로 생성된 세션 아이디를 전달합니다.

  2. 서버는 세션 데이터를 서버 메모리에 저장합니다.

  3. 서버는 브라우저로 response와, 세션 아이디를 담은 쿠키를 전달합니다.

    ❗️ 서버가 브라우저로 보내는 응답의 헤더 중 Set-Cookie 헤더에 세션 아이디 값을 함께 실어 보낸다.
    (서버: 옜다, 너 인증 성공! 🍪 줄게!)

  4. 브라우저는 쿠키를 저장합니다.

    ❗️ 그 응답을 받은 브라우저는 해당 쿠키를 저장하고, 그 다음 매 요청마다 세션 아이디를 Cookie 헤더에 실어 전송한다.
    ⭐️ 이제 브라우저는 이 쿠키를 통해 서버에게 인증된 사용자임을 알릴 수 있다. ⭐️

2. 데이터 송수신 방법

이제 브라우저는 🍪쿠키🍪를 가지고 인증도 했겠다, 서버로부터 인가도 받아보겠습니다.

먼저, 브라우저에서 서버로 데이터를 요청해보겠습니다.

  • 데이터 송신 방법

    1. 저장된 쿠키를 Set-Cookie 헤더에 담아 서버에 데이터를 요청합니다.
    2. 서버는 쿠키에 담긴 session db에 session id를 전달합니다.
    3. Session DB는 전달 받은 session id를 조회합니다.

  • 데이터 수신 방법

    4. Session DB는 서버로 session id에 대한 유효성을 전달합니다.
    5. 서버는 reqeust에 대한 response를 전달합니다.

    🙂: session id가 유효하면 인증된 사용자이므로 사용자에게 필요한 기능을 인가하고, 유효하지 않으면 인증 처리를 해주지 않습니다. 당연히 필요한 기능에 대해 인가 받지 못 할테구요.


2. 세션이 쓰이는 기능

세션 인증 방식을 사용하면 서버는 세션DB를 이용해 로그인된 모든 유저 정보를 저장합니다. 이러한 특징을 통해 다음과 같은 기능들이 가능합니다.

1. 인xx그램: 원치 않는 디바이스 강제 로그아웃
서버에서 session id를 삭제하여 강제 로그아웃 기능을 구현할 수 있습니다.

2. 넷xxx: 다중 로그인 된 계정이 현재 접속 중인지 확인할 수 있음
서버에서 다중 로그인된 계정을 찾아 현재 접속 중인지 확인할 수 있습니다.


3. 장단점

세션을 통한 인증 및 인가 방식에 대해 알아보았습니다. 이러한 방식에는 어떠한 장단점이 있는지 알아봅시다.

1. 장점

  • 서버 측에서 유저의 인증 정보를 관리하기 때문에, 토큰 인증 방식(뒤 포스팅에 게시 예정)과 달리 쉽게 탈취될 가능성이 적어 보안성이 높습니다.
  • 새로고침이나 브라우저 종료 등으로 인한 세션 만료 기간 설정이 가능합니다.
  • 브라우저에서 인증 정보를 노출시키는 위험을 줄일 수 있습니다.

2. 단점

  • 브라우저에서 서버로 데이터를 요청할 때마다 서버에서 세션 정보를 확인해야 하기 때문에, 서버의 부하가 증가할 수 있습니다.
  • 서버에서 직접 사용자 인증 값을 저장하기 때문에 사용자가 많아지게 된다면 서버의 메모리가 부족해 질 수도 있습니다. 결국 사용자가 늘어나게 되면 원활한 접속을 위해 서버를 확장해야 할 것입니다.

서버의 부담을 줄일 수 있는 인증방식은 없을까?
세션 인증 방식의 단점을 보완하기 위해 토큰 인증 방식이 등장하게 되었습니다.

요 부분은 다음 포스팅에서 뵙겠습니다...!! 🤓🤓



참고

https://hudi.blog/cookie-and-session/
https://www.youtube.com/watch?v=tosLBcAX1vk
https://kindjjee.tistory.com/139
https://www.daleseo.com/http-cookies/
https://www.daleseo.com/http-session/
아이콘
https://icon-icons.com/ko/
https://www.flaticon.com/kr/

profile
👩🏻‍💻 Clean Code와 Refactoring에 관심이 많은 개발자 입니다.
post-custom-banner

0개의 댓글