8 분 소요


1. HTTP 프로토콜의 특성

쿠키와 세션은 HTTP 프로토콜의 특성을 보완하기 위해서 사용한다.

HTTP 특성 서명
Connectionless (비연결지향) 클라이언트가 요청을 한 후 서버가 응답을 보내면 그 연결을 끊어 버린다.
stateless (무상태성) 연결을 끊는 순간 클라이언트와 서버의 통신이 끝나며 상태 정보는 유지하지 않는다.


HTTP의 2가지 특성인 Connectionless 과 stateless 로 인해 서버는 클라이언트의 상태를 알 수 없다는 문제가 있다.

  • 예를들어 클라이언트의 상태를 서버가 알지 못한다면 페이지를 이동할 때마다 로그인을 다시 해야 할 것이다.
  • 따라서 클라이언트의 상태를 알기 위해 ( ex.인증↗️ ) 쿠키와 세션을 사용한다.



2. 쿠키(Cookie) 개요

2.1 쿠키 개념

  • 브라우저에 저장되는 텍스트 파일을 말한다. key-value 형태로 저장된다.
  • 쿠키는 클라이언트 측에서 관리되며, 사용자의 컴퓨터에 있는 파일 시스템이나 메모리에 저장된다.

2.2 쿠키 특징

  • 쿠키는 사용자 인증이 유효한 만료일(저장 기간) 설정할 수 있으며, 별도로 삭제처리하거나 유효기간이 만료되지 않는 이상 서버와 통신할 때 자동으로 주고 받게 된다.
  • 저장된 쿠키는 클라이언트 로컬 PC(하드 드라이브에 텍스트 파일)에 저장되며, 각각의 쿠키는 이름, 값, 만료 날짜/시간, 도메인 등의 속성을 가진다.
  • 서버에 특정 API 요청을 했을 때 서버가 응답 시 header 안에 set-cookie 속성으로 쿠키 정보를 담아주면, 클라이언트는 그 쿠키를 받아 로컬에 저장한다.


2.3 쿠키 인증 과정

자료: Web Authentication(인증)_세션/쿠키방식


  1. 클라이언트가 페이지를 요청(사용자가 웹사이트에 접근) 하면 웹 서버에서 쿠키를 생성한다.
  2. 클라이언트가 요청을 보낼 때, 웹 서버는 HTTP 헤더에 쿠키를 포함시켜 응답한다.
  3. 응답을 받은 브라우저(클라이언트)는 쿠키를 브라우저에 자동으로 저장한다.
    1. 저장된 쿠키정보는 [ 개발자도구 → 애플리케이션 → 저장용량 → 쿠키 ] 에서 확인 가능
  4. 동일 사이트 재방문시 클라이언트의 PC에 해당 쿠키가 있는 경우, 브라우저에 저장되어 있는 쿠키는 자동으로 서버에 보내진다. (단, 동일한 Origin 또는 CORS를 허용하는 Origin에만 쿠키를 보낸다. ex- 유튜브 서버에서 받은 쿠키는 유튜브 이용 시에만 주고 받을 수 있다.)
  5. 이전 상태 정보를 변경할 필요가 있을 때 웹 서버는 HTTP 헤더에 “Set-Cookie”를 포함시켜 클라이언트에게 전송하고, 브라우저는 이 응답을 받아 쿠키를 자동으로 업데이트한다.


2.4 Origin과 CORS

Origin 이란?

origin(출처) 이란 protocol + host + port 를 의미한다.


CORS 란?

  • Cross Origin Resource Sharing(CORS)는 다른 origin(출처) 에 리소스 요청하는 것을 허용하는 정책을 말한다.
  • 브라우저는 보안상의 이유로 기본적으로 Same Origin Policy(SOP)를 원칙으로 하고 있지만, 서버와 클라이언트 각각 CORS 설정을 통해 상호합의된 웹사이트는 예외적으로 서로 다른 출처(Cross-Origin)임에도 API 요청이 가능하다.


2.5 쿠키의 유효 기간

쿠키의 유효 기간은 설정에 따라 다르다.

유효기간

  • 클라이언트가 서버에 접속하는 동안, 즉 세션이 유지되는 동안에만 저장되며, 웹 브라우저를 닫으면 자동으로 삭제된다.
  • 클라이언트와 서버 간의 세션 연결을 유지하는 데 사용된다.

저장 위치

웹 브라우저의 메모리에서 저장

사용 예시

로그인 세션이나 쇼핑몰 장바구니와 같이, 사용자가 사이트를 탐색하는 동안만 필요한 정보를 저장하는 데 사용된다.

설정

서버에서 쿠키를 설정할 때 만료 시간을 지정하지 않으면, 자동으로 세션 쿠키가 된다.


유효기간

명시된 만료 시간 또는 유효 기간까지 유지된다. 만료 시간은 Set-Cookie 헤더에서 Expires 또는 Max-Age 속성을 사용해 설정할 수 있다.

저장 위치

사용자의 하드디스크에 저장

사용 예시

  • 사용자의 로그인 상태를 유지
  • 사용자의 선호 설정(예: 언어 설정)을 기억
  • “오늘 이 창 다시 보지 않기” 팝업창 설정 기억
// 쿠키가 7일(604800초) 동안 유지된다는 의미
Set-Cookie: username=JohnDoe; Max-Age=604800; Path=/



3. 세션(Session) 개요

3.1 세션 개념

  • 클라이언트와 서버 간의 데이터를 유지하기 위한 방법으로, 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때까지 인증상태를 유지하는 것을 말한다.(=사용자와 서버 간의 연결이 활성화된 상태를 의미하는 개념)
  • 세션 데이터는 서버에서 관리된다. 클라이언트 측에서는 세션 ID만을 저장하고, 실제 세션 데이터는 서버의 메모리나 데이터베이스에 저장한다.
  • 쿠키라는 정보 자체를 주고받는 것은 다르지 않지만, 로그인과 같은 개인 민감 정보를 다루기 위해 사용된다.


3.2 세션 특징

  • 서버측 관리: 세션 데이터는 서버에 저장되며, 클라이언트 측에서는 고유한 세션 ID만 저장한다.
  • 세션 ID: 서버는 각 클라이언트에게 고유한 세션 ID를 부여하며, 클라이언트는 이 세션 ID를 통해 서버와 상호작용한다.
  • 보안: 브라우저를 닫거나, 서버에서 세션을 삭제했을 때만 삭제가 되므로 쿠키보다 비교적 보안에 좋다.
  • 용량 제한: 서버 용량이 허용하는 한 저장 데이터에 제한이 없지만, 사용자가 많을 경우 많은 자원을 소모한다.
  • 유효기간: 만료시간을 정할 수 있지만 브라우저가 종료되면 만료시간에 상관없이 삭제된다.

⚠️ 세션은 사용자의 수 만큼 서버 메모리를 차지하기 때문에, 토큰 기반의 인증방식 JWT(JSON Web Token)를 사용하는 추세라고 한다.


3.3 세션 인증 과정

자료: 서버 인증 방식(쿠키/세션/토큰)


  1. 사용자가 로그인하면 서버는 새로운 세션을 생성하고(세션 데이터는 객체 형태), 이 세션에 대해 고유한 세션 ID를 발급한다.
  2. 서버는 생성한 세션 ID를 클라이언트의 브라우저에 쿠키 형태로 전달한다. 클라이언트의 브라우저는 이 쿠키를 저장한다.
  3. 클라이언트가 이후 서버에 요청을 보낼 때마다, 브라우저는 저장된 쿠키(세션 ID)를 함께 서버로 전송한다.
  4. 서버는 클라이언트가 전송한 세션 ID를 사용해 서버 측에 저장된 세션 데이터를 조회한다. 이 데이터에는 사용자의 정보나 세션과 관련된 상태가 포함되어 있다.
  5. 서버는 세션 데이터를 조회한 후, 필요한 경우 업데이트를 수행하고, 클라이언트의 요청에 대한 응답을 생성하여 클라이언트에게 전송한다.
  6. 세션 만료 및 종료
    1. 세션 만료: 세션에는 만료 시간이 설정될 수 있으며, 일정 시간 동안 활동이 없으면 세션이 만료된다. 서버는 만료한 세션을 무시하거나 삭제한다.
    2. 세션 종료: 사용자가 로그아웃하면 서버는 세션을 종료하고 클라이언트의 쿠키에서 세션 ID를 삭제하거나 무효화한다.


❓사용자가 브라우저를 닫았다고 해서 세션 데이터가 삭제되는 것은 아니지만 쿠키는 삭제되는거면 여기서 말하는 세션 데이터는 뭘까 궁금해졌다.

  • 세션 데이터는 서버 측에서 사용자의 상태나 관련 정보를 저장하는 데이터를 말한다. 즉, 사용자가 브라우저를 닫으면 세션 쿠키가 삭제되지만, 서버의 세션 데이터는 여전히 남아 있기 때문에 서버는 세션 ID를 통해 세션 데이터를 식별하고 관리할 수 있는 것이다.
  • 만약 브라우저를 다시 열고 같은 사이트에 접속하면, 클라이언트는 새로운 세션 쿠키를 받거나 세션이 만료되지 않은 경우 이전 세션을 복구할 수 있다.


3.5 사용 예시

  • 화면이 이동해도 로그인이 풀리지 않고 로그아웃하기 전까지 유지


3.4 쿠키 vs 세션

먼저 표를 통해 쿠키와 세션의 차이점을 살펴보자 (아래 표: 쿠키(Cookie), 세션(Session) 특징 및 차이)

  쿠키 세션
저장 위치 클라이언트(=접속자 PC) 웹 서버
저장 형식 text Object
만료 시점 쿠키 저장시 설정 (브라우저가 종료되도, 만료시점이 지나지 않으면 자동삭제되지 않음) 브라우저 종료시 삭제 (기간 지정 가능)
사용하는 지원(리소스) 클라이언트 리소스 웹 서버 리소스
용량 제한 총 300개, 하나의 도메인 당 20개, 하나의 쿠키 당 4KB(=4096byte) 서버가 허용하는 한 용량제한 없음
속도 세션보다 빠름 쿠키보다 느림
보안 세션보다 안좋음 쿠키보다 좋음


쿠키와 세션의 가장 큰 차이점은 “상태 정보의 저장 위치”이다.

  • 쿠키는 사용자 정보를 클라이언트(=로컬PC)에 저장하고, 세션은 서버에 저장한다.
  • 때문에 쿠키는 서버의 자원을 전혀 사용하지 않으며, 세션은 서버의 자원을 사용한다.
  • 보안은 세션이 더 높으며, 요청 속도는 쿠키가 빠르다. (세션은 서버 처리 필요하기 때문)


왜 쿠키를 주로 사용할까?

  • 세션은 서버 자원을 사용하기 때문에 사용자가 많을 경우 많은 자원을 소모하여 속도가 느려질 수 있기 때문에 쿠키를 주로 사용한다.



4. JWT(토큰 기반 인증 방식) 개요

4.1 토큰(token) 개념

클라이언트에서 보관하는 암호화된 인증 정보를 의미한다. (세션은 서버에서 보관)

  • 세션처럼 서버에서 사용자의 인증 정보를 보관할 필요가 없기 때문에 서버 부담을 줄여주는 인증 수단이다.
  • 웹에서 인증 수단으로 사용되는 토큰은 주로 JWT (Json Web Token) 을 이용한다.

4.2 JWT 개요

  1. JWT는 인증에 필요한 정보들을 암호화 시킨 Json 토큰이다.
  2. JWT는 Base64로 인코딩되어 “eyJ”로 시작되는 아주 긴 문자열이다.
  3. 이 문자열 안에 .(점)을 구분자로 나뉘어 header.payload.signature 세 부분으로 구성되어있다.
    ① 헤더: 토큰 타입, 암호화 알고리즘 명시
    ② 페이로드: JWT에 넣을 데이터, JWT 발급 / 만료일 등 명시
    ③ 시그니처: 헤더, 페이로드가 변조 되었는지를 확인하는 역할
  4. 암호화된 토큰을 누구나 복호화하여 payload를 볼 수 있다. → 토큰의 용도는 인증정보(payload)에 대한 보호가 아니라 위조 방지
    1. 페이로드의 정보를 보호해야 하는 경우, 암호화 기법을 추가로 적용해야 한다.
  5. 정보(payload)를 토큰화할 때 signature에 secret key가 필요하고, secret key는 복호화가 아니라 토큰이 유효한 지를 검증하는 데 사용된다.

JWT 정보 확인하기 : https://jwt.io/


4.3 JWT 인증 방식

  1. 로그인 요청: 사용자가 서버에 로그인 요청을 보낸다. (EX: 사용자 이름과 비밀번호).
  2. JWT 발급: 서버는 인증 절차를 수행하고, 인증이 유효하면 Base64로 인코딩된 JWT를 생성하여 클라이언트에게 발급한다.
  3. JWT 포함 요청: 사용자(클라이언트)는 요청 시 요청 헤더의 Authoriztion에 발급 받은 JWT를 “Bearer JWT 토큰” 형식으로 담아 보낸다.
  4. 서버 검증 및 응답: 서버는 요청을 받을 때 JWT를 검증하고, 토큰에 포함된 사용자 정보를 사용해 요청을 처리한다. 이때, 서버는 DB 조회 없이도 JWT로 사용자를 식별할 수 있다.


자료: 서버 인증 방식(쿠키/세션/토큰)


4.4 JWT 장점

  • 무상태성(Stateless)
    • 서버가 사용자의 상태를 유지할 필요가 없으므로, 서버 자원을 절약하고 확장성을 높일 수 있다. 서버는 클라이언트의 요청마다 토큰만 검증하면 된다.
  • 저장소 불필요
    • 별도의 세션 저장소가 필요 없다.
  • 시스템 간 권한 공유
    • JWT는 다른 시스템에 접근하거나 권한을 공유하는 데 사용될 수 있어, 여러 서비스 간의 통합에 유리하다.
  • 분산 시스템과 MSA에 유용
    • 클라이언트가 인증 정보를 직접 가지고 있으므로, 분산 시스템과 마이크로서비스 아키텍처(MSA)에서 매우 유용하다.
  • 모바일 환경에서 최적화
    • 세션을 사용할 수 없는 모바일 환경에서도 잘 작동하며, JWT를 활용하여 쉽게 인증을 처리할 수 있다.


4.5 JWT 단점

  • 토큰 크기와 네트워크 부하
    • 많은 양의 데이터를 JWT의 페이로드에 저장하면, JWT의 크기가 커져 네트워크 부하가 발생할 수 있다.
  • 페이로드의 보안성
    • JWT의 페이로드는 Base64로 인코딩되어 있지만 암호화되지 않다. 따라서 페이로드의 정보를 쉽게 디코딩하여 볼 수 있기 때문에 민감한 정보를 저장해서는 안된다.
  • 토큰 탈취 위험
    • 클라이언트가 JWT를 저장하고 있기 때문에, 토큰이 탈취되면 인증 정보를 악용할 수 있다. 토큰이 탈취되면 무효화하기 어렵기 때문에 HTTPS를 통해 토큰 전송을 암호화하고, 유효 기간리프레시 토큰을 사용하여 위험을 최소화해야한다.


그럼 유효 기간을 어떻게 두어야 할까?

  • 유효기간을 짧게 두면 사용자가 로그인을 자주 해야하므로 사용자 경험적으로 좋지 않고, 유효기간을 길게 두면 보안상 탈취 위험에서 벗어날 수 없을 것이다.
    • Access Token의 유효기간은 짧다.
    • Refresh Token의 유효기간은 길다.
  • 즉, 통신과정에서 탈취당할 위험이 큰 Access Token의 만료 기간을 짧게 두고 Refresh Token으로 주기적으로 재발급함으로써 보안과 사용자 경험을 균형 있게 유지할 수 있다.


✨ JWT의 “Access Token”과 “Refresh Token”에 대해서 자세히 알아보자!



5. JWT의 Access Token과 Refresh Token

5.1 쿠키의 HttpOnly 옵션

  • JavaScript를 통한 쿠키 접근을 막아 XSS 공격을 방지하여 보안을 강화한다.
  • 이 옵션을 설정하면 쿠키는 서버 측 요청 시에만 전송되며, 클라이언트 측 스크립트에서는 접근할 수 없다.
  • 이 경우, JS를 통해 토큰 접근을 못하기 때문에 토큰을 처리하기 위해 토큰 2개를 사용한다.


5.2 Access Token과 Refresh Token

  • Access Token

    • 사용자가 인증 후 서버 리소스에 접근할 때 사용하는 토큰이다.(인증/인가시 사용)
    • 토큰이 탈취되더라도 오랜 시간동안 유용한 인증 정보를 가지고 있지 못하기 하기 위해 유효기간이 짧게 잡아 보안을 강화한다.
    • 일반적으로 30분 정도의 짧은 기간을 가지며, 인증 상태를 지속시키기 위해 자주 갱신된다.
    • 일반적으로 Heap 메모리(변수)에 저장한다.

  • Refresh Token

    • Access Token이 만료되었을 때 새로운 Access Token을 발급받기 위해 사용되는 토큰이다.
    • 유효 기간이 긴 경우가 많으며, 일반적으로 1~2주 정도의 기간을 가진다.
    • 사용자가 자주 로그인하는 불편함을 줄여준다.
    • 일반적으로 HttpOnly 쿠키에 저장한다.

💡 즉, 서버에서는 Access Token이 만료되었을 때 Refresh Token 이 유효한 상태면 새로운 Access Token을 클라이언트에 발급해주고 인증상태를 유지할 수 있도록 하고, Refresh Token 만료 시 다시 로그인하라는 메시지를 응답한다.


5.3 인증 과정

  1. 사용자(클라이언트)가 로그인 시, 서버는 사용자의 인증 절차를 확인하고, 인증이 유효한 경우 Access Token과 Refresh Token을 클라이언트에게 발급한다.
  2. 클라이언트는 받은 JWT를 로컬 스토리지, 세션 스토리지, 쿠키 등 적절한 저장소에 저장한다.
  3. 클라이언트는 서버에 요청할 때 JWT를 포함시킨다. 일반적으로 HTTP 헤더의 Authorization 필드에 Bearer <token> 형식으로 담아 보낸다.
  4. 서버는 JWT를 받아서 서명을 검증하고, 페이로드의 클레임을 확인하여 요청의 유효성을 판단한다.
  5. 서버는 요청이 유효하다면 필요한 데이터를 반환하고, 그렇지 않으면 오류 응답을 반환한다.


5.4 세션 인증 vs. 토큰 인증

  세션 인증 토큰 인증
인증정보 저장 위치 서버 클라이언트
확장성(Scale-out) Bad Good
보안성 (상대적) Good Bad
비용 (상대적) Expensive Cheap



6. 참조


카테고리:

업데이트:

댓글남기기