웹 인증(Authentication)을 위한 쿠키, 세션, 그리고 JWT 이해하기

Dukov·2024년 4월 5일
0

Web development

목록 보기
1/3
post-thumbnail

웹 개발에 있어서 사용자 세션과 인증 관리는 안전하고 효율적인 애플리케이션을 만드는데 있어 필수적입니다.

이번 포스트에서는 인증 및 세션 관리에서 중요한 역할을 하는 세 가지 기본 개념인 쿠키(Cookies), 세션(Sessions), JWT에 대해 알아보도록 하겠습니다.


쿠키 (Cookie)란?

HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각입니다.
브라우저는 그 데이터 조각들을 저장해 놓았다가, 동일한 서버에 재 요청 시 저장된 데이터를 함께 전송합니다.
쿠키는 두 요청이 동일한 브라우저에서 들어왔는지 아닌지를 판단할 때 주로 사용합니다.
이를 이용하면 사용자의 로그인 상태를 유지할 수 있습니다. 상태가 없는(stateless) HTTP 프로토콜에서 상태 정보를 기억시켜주기 때문입니다.
- MDN: HTTP 쿠키

쿠키 (Cookie)는 웹사이트가 상태 저장 정보(예: 온라인 상점의 장바구니에 추가된 품목)를 기억하거나 사용자의 검색 활동(특정 버튼 클릭, 로그인 또는 과거에 방문한 페이지 기록 등)을 기록하기 위해 만들어졌습니다.

우리는 쿠키를 이름, 주소, 비밀번호, 결제 카드 번호 등 사용자가 이전에 양식 필드에 입력한 정보를 기억하는 용도로 사용할 수 있고, 웹 인증을 구현하는 용도로 사용할 수도 있습니다.

쿠키의 종류

  1. 세션 쿠키: 임시 쿠키라고도 하는 세션 쿠키는 사용자가 웹사이트를 방문하는 동안 사용자의 브라우저에 일시적으로 생성됩니다. 세션 쿠키는 사용자가 브라우저를 닫으면 삭제됩니다.

  2. 영구 쿠키: 영구 쿠키 또는 저장 쿠키라고도 하는 영구 쿠키는 사용자의 브라우저에 저장되며 설정된 만료일까지 유효합니다(만료일 전에 사용자가 삭제하지 않는 한). 영구 쿠키는 웹 서핑 행동이나 특정 웹사이트에 대한 사용자 기본 설정 등 사용자에 대한 식별 정보를 수집하는 데 사용됩니다.

쿠키와 보안

쿠키는 사용자 행동을 추적하고 분석하는 데 사용될 수 있습니다. 따라서 쿠키를 사용할 때 개인정보 보호 및 보안에 주의해야 합니다.

많은 웹 브라우저에서는 사용자가 쿠키 기본 설정을 관리하여 특정 사이트의 쿠키를 제한하거나 차단할 수 있습니다.

또한 유럽연합의 일반 데이터 보호 규정(GDPR) 및 기타 개인정보 보호법에 따라 웹사이트는 쿠키를 배치하기 전에 사용자의 동의를 얻어야 합니다.

요새 해외 사이트 등에 접속할 때 쿠키 동의 요청 팝업이 뜨는 것도 GDPR을 준수하기 위함이라고 합니다.

세션 없이 쿠키만 단독 사용하는 경우

일반적으로 쿠키로만 웹 인증을 구현하는 것은 보안에 매우 취약하기 때문에 권장되지 않습니다.

그럼에도 불구하고 쿠키만 단독으로 사용하는 경우들이 있는데, 다음과 같습니다:

  • 사용자 설정 저장: 민감정보가 아닌 단순 사용자 설정(테마, 언어 등) 등을 쿠키에 저장하는 경우.

  • 클라이언트 사이드 트래킹: 서버의 개입 없이 사용자의 활동을 추적하고자 하는 경우 쿠키를 사용합니다.

  • JWT 등 인증 토큰을 담는 경우: 토큰을 쿠키에 담아서 사용하는 경우 세션 없이 웹 인증을 구현할 수 있습니다.


세션 (Session)이란?

세션 (Session)은 사용자 또는 브라우저 세션과 관련된 정보의 서버 측 저장소입니다.

웹 서버는 세션을 사용해 여러 HTTP 요청에 걸쳐 상태를 저장할 수 있습니다.

쿠키와 달리, 세션 데이터는 각 HTTP 요청과 함께 전송되지 않아 데이터 전송량을 줄이고 보안을 높입니다.

세션 데이터는 애플리케이션의 확장성과 보안 요구 사항에 따라 메모리 내 저장소(Redis 등), 데이터베이스, 또는 파일 시스템 등 다양한 방식으로 저장됩니다.

세션의 작동 방식

사용자가 웹 애플리케이션에 접속하면 서버는 해당 사용자의 세션에 대한 고유 세션 식별자(세션 ID)를 생성합니다.

이 세션 ID는 일반적으로 쿠키 형태로 클라이언트의 브라우저로 전송되며, 이후 요청이 있을 때마다 서버로 다시 전송됩니다.

이를 통해 서버는 세션 ID를 기반으로 저장된 세션 데이터를 검색하여 요청 사이에 사용자의 상태나 활동을 효과적으로 기억할 수 있습니다.

세션의 특징

  1. 상태 관리: 세션은 여러 HTTP 요청에 걸쳐 사용자 상태를 보존하는 방법을 제공하며, 이는 stateless한 HTTP 프로토콜에서 개인화된 사용자 경험을 만들고, 인증을 구현할 수 있게 합니다.

  2. 보안: 세션 데이터는 서버에 저장되므로 민감한 정보가 클라이언트의 브라우저에 노출되지 않습니다. 따라서 세션은 쿠키만 단독으로 사용하는 것에 비해 보안 측면에서 더 안전합니다.

  3. 유연성: 세션은 다양한 데이터 유형과 구조를 저장할 수 있으므로 사용자 인증, 장바구니, 사용자 기본 설정 등 다양한 요구사항에 따라 다양하게 활용할 수 있습니다.

세션의 종류

  1. 임시 세션: 이러한 세션은 일시적이며 일반적으로 사용자 브라우저 세션의 수명에 연결됩니다. 브라우저를 닫으면 삭제됩니다.

  2. 영구 세션: 이러한 세션은 서버 또는 데이터베이스에 보다 영구적으로 저장되며 미리 정의된 만료 시간에 따라 여러 브라우저 세션에 걸쳐 지속될 수 있습니다.

세션 관리 방법

PHP, Ruby on Rails, Django(Python), Express(Node.js) 등의 웹 개발 프레임워크와 언어는 세션 관리를 기본적으로 지원하여 세션을 만들고 관리하는 프로세스를 간소화합니다.

Express 환경에서는 express-session 모듈을 사용하면 간편하게 세션을 만들고, 관리할 수 있습니다.

세션과 보안

세션은 클라이언트 측 쿠키보다 더 안전하지만 세션 하이재킹 같은 취약점이 없는 것은 아닙니다.

따라서 세션 보안을 위해 세션 만료기간 설정, HTTP 전용 쿠키 사용 등 조치가 필요합니다.


쿠키와 세션으로 인증 구현하기

쿠키와 세션을 함께 사용하는 것은 사용자 인증을 관리하는 일반적이고 효과적인 방법입니다.

일반적으로 서버는 로그인 성공 시 사용자의 세션을 생성하고, 사용자의 브라우저에 세션ID가 담긴 쿠키를 저장한 다음, 이후 요청때마다 사용자의 쿠키를 확인하여 사용자의 세션 데이터를 검색하는 프로세스를 거칩니다.

이렇게 쿠키와 세션을 사용해 인증을 구현하면 사용자가 다시 로그인하지 않아도 서버는 여러 요청에 걸쳐 사용자를 인식할 수 있습니다.

인증 구현 과정

1. 유저 로그인

사용자가 로그인 자격 증명(일반적으로 사용자 이름과 비밀번호)을 제출하면 서버는 DB에 저장된 사용자 데이터와 비교하여 자격 증명을 확인합니다.

2. 세션 생성하기

로그인에 성공하면 서버가 새 세션을 생성합니다. 세션 데이터에는 사용자의 ID, 역할, 기본 설정 등 사용자의 세션과 관련된 모든 것이 포함될 수 있습니다.

세션 데이터는 메모리, 데이터베이스, 세션 스토어, 세션 관리 서비스 등을 통해 서버에 저장됩니다.

3. 쿠키 전송하기

서버는 세션 ID를 쿠키에 담아서 클라이언트의 브라우저에 전송합니다. 이 쿠키는 이후 브라우저의 모든 요청에 포함됩니다.

쿠키가 HTTPS를 통해서만 전송되도록 하려면 응답 헤더의 Set-Cookie 부분에 Secure 속성을 추가합니다.

클라이언트 측 스크립트가 쿠키에 액세스하지 못하도록 하여 크로스 사이트 스크립팅(XSS) 공격에 대한 보안을 강화하려면 응답 헤더의 Set-Cookie 부분에 HttpOnly 속성을 추가합니다.

4. 세션 유지하기

세션 ID 쿠키가 설정되면 이후 클라이언트 브라우저의 각 요청에 이 쿠키가 포함됩니다.

서버는 쿠키에서 세션 ID를 읽고 해당 세션 데이터를 조회하여 사용자의 인증 상태 및 권한을 확인합니다.

5. 만료된 세션 처리하기

보안상의 이유로 세션에는 만료시간이 설정되어야 합니다.

세션이 만료되면 서버에서 세션 데이터가 삭제되고, 해당 세션 ID가 담긴 쿠키는 더 이상 유효하지 않게됩니다.


JWT (JSON Web Tokens)란?

JSON 웹 토큰(JWT)은 당사자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준(RFC 7519)입니다. 이 정보는 디지털 서명이 되어 있기 때문에 검증되고 신뢰할 수 있습니다. JWT는 비밀(HMAC 알고리즘 사용) 또는 RSA 또는 ECDSA를 사용하는 공개/개인 키 쌍을 사용하여 서명할 수 있습니다.
- jwt.io: JWT 소개

JWT (JSON Web Token)는 쿠키와 세션을 사용하는 전통적인 인증 방식과 달리, 사용자 인증 정보를 JSON 포맷으로 안전하게 전송할 수 있는 토큰 기반의 인증 방식입니다.

JWT는 헤더, 페이로드, 그리고 서명의 세 부분으로 구성됩니다.

헤더는 토큰의 타입과 사용된 해싱 알고리즘에 대한 정보를 담고 있습니다.

페이로드에는 실제 전송하고자 하는 데이터(예: 사용자의 정보)가 포함됩니다.

마지막으로, 서명은 토큰이 변조되지 않았음을 검증하기 위해 사용됩니다.

JWT의 작동 방식

JWT는 헤더, 페이로드, 서명의 세 부분으로 구성됩니다. 각 부분은 점(.)으로 구분됩니다.

  1. 헤더 (Header): 헤더는 일반적으로 두 부분으로 구성됩니다. 토큰의 유형(JWT)과 사용 중인 서명 알고리즘(예: HMAC SHA256 또는 RSA)입니다.

  2. 페이로드 (Payload): 페이로드에는 클레임(Claim)이 포함됩니다. 클레임은 사용자와 추가 메타데이터에 대한 정보입니다. 클레임에는 등록 클레임, 공개 클레임, 비공개 클레임의 세 가지 유형이 있습니다.

  3. 서명 (Signature): 서명 부분을 만들려면 인코딩된 헤더, 인코딩된 페이로드, 비밀 키, 헤더에 지정된 알고리즘을 가져와서 서명해야 합니다.

예를 들어 서버는 '관리자 권한으로 로그인함'이라는 클레임이 있는 토큰을 생성하여 클라이언트에 제공할 수 있습니다.

그러면 클라이언트는 이 토큰을 서버에 전송하는 것 만으로도 자신이 관리자로 로그인했음을 증명할 수 있습니다.

서버는 토큰의 서명을 확인해서 유효성을 검증하고, 페이로드의 클레임을 이용해 사용자를 인증합니다.

JWT는 보통 응답 헤더에 포함되거나 쿠키에 담겨서 전송됩니다.

JWT 클레임의 유형

  • 등록된 클레임: 필수 사항은 아니지만 권장되는 미리 정의된 클레임 세트입니다. 여기에는 iss(발행자), exp(만료 시간), sub(대상) 등이 포함됩니다.

  • 공개 클레임: JWT를 발행하는 사람이 마음대로 정의할 수 있습니다. 충돌을 방지하려면 URI 형식으로 정의하는게 좋습니다.

  • 비공개 클레임: 비공개 클레임은 사용하기로 동의한 당사자 간에 정보를 공유하기 위해 만든 사용자 지정 클레임입니다.

JWT의 장점

  1. 컴팩트함: JWT는 URL, POST 매개변수 또는 HTTP 헤더 내부를 통해 전송할 수 있습니다. 또한 JWT는 크기가 작기 때문에 성능면에서 이점을 가져갈 수 있습니다.

  2. 많은 정보를 포함: 페이로드에는 사용자에 대한 모든 필수 정보가 포함되어 있기 때문에 사용이 용이합니다.

  3. 사용 편의성: 다양한 라이브러리와 도구가 JWT를 지원하므로 웹, 데스크톱 및 모바일 애플리케이션에서 쉽게 구현할 수 있습니다.

  4. 교차 도메인 인증 용이: CORS(교차 출처 리소스 공유) 및 교차 도메인 인증을 용이하게 합니다.

JWT의 단점

  1. 저장상의 문제: 일단 발급된 JWT는 만료되기 전에는 무효화할 수 없습니다. XSS 또는 CSRF 공격을 방지하기 위해 안전하게 저장해야 합니다.

  2. 확장 문제: 서버에 세션 상태가 없으므로 애플리케이션에서 로그아웃을 추적해야 하는 경우 서버에서 따로 로직을 구현해야 합니다.

  3. 보안 문제: JWT 페이로드의 정보는 인코딩되어 있지만 암호화되어 있지 않으므로 가로챌 경우 쉽게 해독할 수 있습니다. 민감한 정보는 JWT에 저장해서는 안 됩니다. 또한 시크릿 키가 유출되거나 탈취 당하지 않도록 해야합니다.


언제, 어떤 방식을 사용해야 할까?

쿠키-세션 방식이 적합한 경우

  • 대부분의 일반적인 경우: 전통적인 방식이며 보안 측면에서 검증된 방법이기 때문에, JWT를 꼭 써야하는 상황이 아닐 때는 쿠키-세션 방식을 고려하는 것이 좋습니다.

JWT 방식이 적합한 경우

  • 단일 페이지 애플리케이션(SPA) 및 모바일 애플리케이션: JWT는 클라이언트 애플리케이션이 다른 서버나 도메인에 API 요청을 해야 하는 경우 사용하기 좋습니다.

  • 확장성이 뛰어난 어플리케이션: JWT는 서버 측 세션 저장소가 필요하지 않으므로 많은 수의 사용자가 예상되는 애플리케이션에 더 확장성이 뛰어납니다.

  • 교차 도메인 인증이 필요한 경우: 애플리케이션에 여러 도메인이 포함되어 있고 이러한 도메인에서 사용자 세션을 유지 관리해야 하는 경우 JWT는 쿠키-세션 방식보다 유연하며 사용하기 편합니다. (예: MSA 등)

결론

쿠키-세션 방식과 JWT는 웹 인증을 구현할때 매우 유용한 도구로 쓸 수 있습니다.

모든 상황에서 무조건 좋은 방식은 없으며, 확장성, 도메인 간 인증의 필요성, 개발 중인 애플리케이션의 유형 등 애플리케이션의 요구 사항에 따라 적합한 방식을 잘 선택해서 사용해야 합니다.


References

MDN: HTTP 쿠키
jwt.io: JWT 소개
코딩애플: JWT 대충 쓰면 님들 코딩인생 끝남
Valentin Despa: Difference between cookies, session and tokens

profile
끊임없이 도전하고, 실패에서 배우는 백엔드 개발자입니다.

0개의 댓글

관련 채용 정보