쿠키, 세션 그리고 토큰

Seop·2023년 7월 6일
0

Web

목록 보기
1/3
post-thumbnail

웹 서버는 사용자를 구분해야합니다.
사용자를 구분해야 사용자에 따라 적절한 서비스를 제공할 수 있기 때문이죠

사용자를 구분하려면 어떻게 해야 할 까요??

그 전에 인증과 인가에 대해서 간단하게 알아봅시다.

인증과 인가

인증 Authentication

인증이란 현재 사용자가 누구인지 검증하는 과정입니다.
즉, 서비스에 접근할 수 있는 사용자인지를 구분하는 과정입니다.

ID/PW를 사용해서 로그인 라는 과정을 인증 과정이라고 생각하면 편합니다.

대표적인 회원제 서비스인 에브리타임을 예를 들어 보겠습니다.

여기 에브리타임 서비스와 두 명의 사용자 있습니다.
한 명은 대학교 학생이라, 학교 메일을 통해 인증을 받은 사용자이고,
다른 한 명은 인증을 하지 않아서 인증되지 않은 익명 사용자(Anonymous User) 입니다.

이 두 명이 각각 에브리타임 서비스에 접근하려고 하면 어떻게 될까요??

인증이 된 학생 유저는 에브리타임 서비스를 이용할 수 있지만, 익명 사용자는 사용할 수 없습니다.
회원제 서비스에서 아무나 들어오는 것은 비즈니스 로직에 부합하지 않으니깐요.


인가 Authorization

인가는 사용자가 특정 컨텐츠에 접근을 시도할 때, 적절한 권한을 가지고 있는지에 대해 검증을 하는 과정입니다.

인증을 받은 사용자라고 하더라도 모든 사용자에게 동일한 컨텐츠를 보여주면 안됩니다.
사용자들은 각자의 권한이 전부 다르기 때문이죠.

인증을 받은 두 명의 사용자가 있다고 해보겠습니다.
그리고 두 명의 사용자는 학교가 다릅니다.

그렇다면 두 명은 각각 본인 학교의 에브리타임에만 접속할 수 있어야만 합니다

만약 B 대학의 학생이 A 대학의 에브리타임에 접속을 시도하면, 인가되지 않은 사용자이기 때문에
에브리 타임은 접근을 거부할 겁니다.

권한이 올바르지 않기 때문이죠


Http 는 stateless

이렇듯 서버는 현재 접속을 시도하는 사용자를 검증해서, 접속을 차단할 것인지, 어떤 정보를 보여줄 것인지 결정해야 합니다.

그런데 http 프로토콜은 상태를 저장하지 않습니다. 다른 말로 stateless 하다고 하죠

그러면 클라이언트와 서버 사이의 인증 및 인가, 권한 등에 대한 정보를 어떻게 공유할까요???
서로 아무런 공유가 되지 않으면 모든 작업이 의미가 없을 텐데 말이죠...

그래서 우리는 사용자에 대한 정보를 서버와 클라이언트 사이에서 서로 주고 받을 필요가 생겼습니다.

그리고 이러한 과정에서 쿠키, 세션, 토큰 등이 사용 되죠.


쿠키 Cookie

내가 만든 쿠키~

HTTP 쿠키(HTTP cookie)란 하이퍼 텍스트의 기록서(HTTP)의 일종으로서 인터넷 사용자가 어떠한 웹사이트를 방문할 경우 사용자의 웹 브라우저를 통해 인터넷 사용자의 컴퓨터나 다른 기기에 설치되는 작은 기록 정보 파일을 일컫는다

위키백과 HTTP 쿠키

쿠키는 브라우저에 저장되는 텍스트입니다.
즉 클라이언트에서 관리하는 정보라고 할 수 있죠.

쿠키의 목적

쿠키는 서버에서 만들어 진 후 사용자에게 전달 되고, 추후 사용자가 다시 요청을 보낼 때 쿠키와 같이 보내게 됩니다.

쿠키는 주로 3가지 목적으로 사용됩니다.

  • 세션관리

로그인, 장바구니, 게임 점수 기록과 등과 같은 서버가 기억해야 할 정보 기록

  • 사용자화/개인화

사용자가 설정한 정보, 테마 등의 정보 기록

  • 추적

사용자의 행위를 기록 및 분석하기 위해 사용자의 정보를 기록

특징

쿠키는 지정된 시간 이후에는 소멸됩니다.

쿠키는 다른 쿠키를 저장할 공간을 위해 또는 서비스 제공측의 비즈니스 로직에 의해 TTL(Time To Live)가 정해져 있습니다.

쿠키는 브라우저간 호환이 되지 않습니다.

사용자의 장바구니를 쿠키에 보관하는 웹사이트에서 쇼핑을 할 때,
크롬 웹 브라우저에서 바나나를 장바구니에 보관했지만.
해당 사이트를 파이어폭스로 다시 들어가면 장바구니에 아무런 품목이 존재하지 않는다는 뜻입니다.

쿠키의 생성에도 제약조건이 존재합니다.

  • 클라이언트는 최대 300개의 쿠키만을 만들 수 있으며
  • 각 쿠키의 크기는 4KB 이하여야만 하고
  • 각 웹사이트에서는 최대 20개의 쿠키만을 생성할 수 있습니다.

위의 장바구니 상황에서 장바구니에 담은 품목이 계속 커지게 되면, 쿠키의 크키가 커지게 됩니다.
그리고 이는 http 요청의 크기가 커지게 됩니다.

쿠키 메커니즘

DO SON on SecurityOnline

쿠키는 다음과 같은 과정으로 생성됩니다.
1. 클라이언트는 서버에 http 요청을 보낸다
2. 서버는 1.의 요청에 대한 응답을 클라이언트로 보낸다
이 때, http 응답의 헤더 부분에 쿠키를 생성토록 하는 Set-Cookie를 포함해서 전송한다
3. 클라이언트는 응답을 기반으로 쿠키를 생성한다.
4. 클라이언트가 서버로 요청을 다시 보낼 때, 이번에는 쿠키를 헤더에 포함해서 보낸다
5. 서버는 요청의 헤더의 쿠키를 기반으로 사용자를 식별한다.


세션 Session

세션은 서버에 저장되는 클라이언트에 대한 정보입니다.
그리고 클라이언트는 쿠키를 통해 본인의 세션 ID를 저장하죠

세션이 생성되고 사용되는 메커니즘은 다음과 같습니다.

Raj Chandel

매커니즘

  1. 클라이언트는 서버로 요청을 보냄
  2. 서버는 클라이언트를 구분하는 세션 ID를 포함해서 응답을 보냄
  3. 클라이언트는 응답으로 받은 세션ID를 쿠키에 저장함
  4. 클라이언트가 다시 서버로 요청을 보낼 때, 본인의 세션ID를 포함해서 보냄
  5. 서버는 요청을 받고 알맞을 행동을 수행함
    1. 만약 일치하는 세션 id가 존재하면, 알맞은 정보를 리턴해줌
    2. 일치하는 세션 id가 없으면 두 가지 경우의 수
      1. 해당 유저는 로그인 한 적이 없음
      2. 세션이 만료된 상태

세션은 서버에 저장됨

정확히는 서버의 로컬 스토리지안에 저장됩니다.
이는 서비스가 싱글 서버로 운영될 때는 문제가 되지 않습니다. 서버 안에 모든 세션 정보가 다 저장되어 있으니깐요

세션의 단점

  1. 멀티 서버 환경에서의 관리

하지만 서비스가 인기가 많아지고, Scale-Up으로는 더 이상 운영상의 요구사항을 감당하기 힘들 때가 올 것입니다.
그러면 Scale-Out, 서버를 늘려야 하죠

이러면 문제가 생깁니다.
세션은 서버의 로컬 스토리지 안에 저장되는데, 사용자가 로드 밸런싱에 의해 다른 서버로 리다이렉팅 되면, 해당 서버의 로컬 스토리지안에는 사용자의 세션 정보가 없으니깐요

로드 밸런서는 부하를 분산했을 뿐인데....
사용자는 본인의 세션 정보가 쓸모 없어졌다

이 문제의 해결 방법은 제 이전 포스팅 - 멀티 서버 환경에서 세션을 유지하는 방법을 참고해 주시면 감사하겠습니다.

  1. 서버에 부하

세션의 정보는 서버에 저장됩니다.
그렇기 때문에 동시에 접속중인 사용자가 많아지면, 서버에 무리가 가겠죠!

그러면 서버는 서버대로 사용자의 세션을 유지하기 위해서 자원을 써야하니까요

  1. 탈취당할 가능성

클라이언트는 세션 ID를 쿠키에 저장합니다.
하지만 쿠키는 외부의 공격에 매우 취약합니다.

브라우저 안에 저장되어 있는 쿠키는 누가 뺏어간 뒤, 해당 세션 ID를 가지고 해커가 '나 인척'을 할 수 있습니다!!


토큰 Token

토큰방식은 세션과는 다른 방식으로 인증 및 인가를 진행합니다.
클라이언트가 서버에 접속을 하면, 서버는 토큰을 발급한 뒤 클라이언트에게 넘겨줍니다.
클라언트는 로컬 스토리지에 잘 저장해 놓습니다.
그리고 클라이언트는 서버에 접근할 때 서버에 토큰을 넘겨주죠.
서버는 클라이언트로 부터 받은 토큰을 검증만 합니다!!
서버는 토큰을 저장하지 않죠.

만약 토큰이 유효한 토큰이면 사용자에게 알맞을 리소스를 리턴해 주면 되고, 아니면 접근을 차단합니다.

JWT (Json Web Token)

JSON 웹 토큰(JSON Web Token, JWT, "jot”1은 선택적 서명 및 선택적 암호화를 사용하여 데이터를 만들기 위한 인터넷 표준으로, 페이로드는 몇몇 클레임(claim) 표명(assert)을 처리하는 JSON을 보관하고 있다.

JWT 위키백과

JWT는 다음과 같은 구조로 이루어져 있습니다.

  • Header
{
 "alg" : "HS256",
 "typ" : "JWT"
}

헤더는 어떤 알고리즘을 사용할지 등의 정보를 포함하고 있습니다.

  • Payload
{
 "loggedInAs" : "admin",
 "iat" : 1422779638
}
  • Signature
HMAC-SHA256(
 secret,
 base64urlEncoding(header) + '.' +
 base64urlEncoding(payload)
)

Access Token 과 Refresh Token

Access Token이란 실질적으로 인증 및 인가 작업을 수행하는 토큰입니다.
이 녀석만 있으면 인증/인가 작업을 잘 수행할 수 있죠.

하지만 문제가 있습니다.
클라이언트가 로컬 스토리지에 잘 보관해서 탈취당하지 않으면 괜찮지만...

이 역시 클라이언트가 보관을 하기 때문에 언제든지 누군가가 탈취를 할 수 있고, 사이트에서 '나 인척' 행세를 할 수도 있죠..!!!

그렇기 때문에 Access Token 은 보통 유효 시간이 짧게 설정해 놓습니다.(30분 정도)

그런데 이렇게 하면 Access Token이 빠르게 만료되고
만료 될 때마다 사용자는 재로그인을 해야합니다

이거는 진짜 귀찮겠죠

이에 대한 해결 방식으로 Refresh Token이 등장합니다.

Refresh TokenAccess Token을 재발행하는 토큰입니다.
사용자는 처음에는 발급받은 Access Token으로 서버의 리소스에 접근을 하다가 Access Token가 만료가 되면 Refresh Token을 사용해서 Access Token을 새로 발급 받습니다.

때문에 Refresh Token은 만료 시간이 꽤 긴 편입니다. (2주 정도)

그림으로 보면 다음과 같습니다!


참고

Cookies, Session, Token

profile
어제보다 더 나은 개발자가 되고파요

0개의 댓글