[Web Security] 로그인 인증의 작동 원리

aiden·2026년 8월 7일

Security/Hacking

목록 보기
6/7

1. 쿠키(Cookie)와 세션(Session)의 등장 배경

HTTP 프로토콜은 두 가지 핵심 특성을 가진다.

  • Stateless (무상태성): 서버는 클라이언트의 이전 상태를 기억하지 않음. 각 요청은 완전히 독립적임.
  • Connectionless (비연결성): 클라이언트가 요청을 보내고 서버가 응답을 마치면 연결을 끊음.

이로 인해 "로그인한 사용자가 페이지를 이동할 때 로그인 상태를 어떻게 유지할 것인가?"라는 문제가 발생한다. 매번 아이디/비밀번호를 요청에 실어 보낼 수는 없으므로, 이를 해결하기 위해 쿠키(Cookie)와 세션(Session) 개념이 도입되었다.


🍪 개념 및 작동 방식

쿠키는 서버가 클라이언트(브라우저)에 저장하는 작은 데이터 조각(Key-Value 형태)이다.

[클라이언트]  --->  (1) 로그인 요청 (ID/PW)  --->  [서버]
[클라이언트]  <---  (2) 응답 + Set-Cookie  <---  [서버]
[클라이언트]  --->  (3) 요청 + Cookie Header --->  [서버] (상태 유지)
  1. 클라이언트가 로그인에 성공하면, 서버는 응답 헤더에 Set-Cookie를 실어 보냄.
  2. 브라우저는 전달받은 쿠키를 저장소에 보관함.
  3. 이후 동일한 도메인으로 요청을 보낼 때마다 브라우저가 자동으로 Cookie 헤더에 담아 전송함.

⚠️ 쿠키의 보안 취약점과 설정 옵션

쿠키는 브라우저에 저장되므로 클라이언트 측에서 손쉽게 조회 및 변조가 가능하다. 이를 방지하기 위한 핵심 플래그 설정이 필수적이다.

  • HttpOnly: JavaScript(document.cookie)를 통한 쿠키 접근을 차단함. XSS(Cross-Site Scripting) 공격으로 인한 쿠키 탈취 방지.
  • Secure: HTTPS 통신 환경에서만 쿠키를 전송하도록 제한함. 네트워크 스니핑 방지.
  • SameSite: Cross-Site 요청 시 쿠키 전송 여부를 제어해 CSRF(Cross-Site Request Forgery) 공격을 방어함.
  • Strict: 타 사이트에서 발생하는 모든 요청에 쿠키 미전송.
  • Lax: 기본값. 링크 클릭 등 일부 Safe 요청에만 쿠키 전송.
  • None: 모든 Cross-Site 요청에 쿠키 전송 (Secure 옵션 필수).

3. 세션 (Session)

🔑 개념 및 작동 방식

쿠키에 민감한 정보(예: 사용자 ID, 권한 등)를 직접 담으면 보안상 매우 위험함. 따라서 민감한 정보는 서버 메모리나 DB에 저장하고, 클라이언트에게는 난수화된 '세션 ID'만 발급하는 방식이 세션 기반 인증임.

[클라이언트]  --->  (1) 로그인 요청           --->  [서버] (인증 성공 후 Session DB에 저장)
[클라이언트]  <---  (2) 응답 + Set-Cookie:    <---  [서버] (JSESSIONID=a1b2c3d4...)
                    JSESSIONID
[클라이언트]  --->  (3) 요청 + Cookie Header --->  [서버] (Session ID 조회 후 사용자 식별)
  1. 클라이언트 로그인 성공 시, 서버는 메모리/DB에 세션 공간을 생성하고 난수 형태의 Session ID를 생성함.
  2. 서버는 Set-Cookie를 통해 Session ID만 클라이언트에 전달함.
  3. 클라이언트는 요청마다 Session ID가 담긴 쿠키를 전송하고, 서버는 세션 저장소에서 해당 ID를 조회해 사용자를 식별함.

📌 세션의 특징 및 단점

  • 장점: 데이터 실체가 서버에 있으므로 쿠키 대비 보안성이 우수함.
  • 단점:
  • 서버 자원 소모: 접속자가 늘어날수록 서버 메모리/DB 부하가 증가함.
  • Scalability(확장성) 이슈: 서버를 여러 대 두는 분산 환경(Load Balancing)에서 세션 공유 문제 발생.
  • (해결책: Redis 같은 In-Memory DB를 활용하여 중앙 세션 서버 구축).

4. 토큰 기반 인증 (JWT: JSON Web Token)

세션의 서버 저장소 부담을 줄이고 Stateless한 구조를 유지하기 위해 자주 사용되는 방식이다.

📄 JWT 구조

JWT는 .을 구분자로 세 부분으로 구성된 문자열이다.

Header.Payload.Signature
  1. Header: 토큰 타입(JWT) 및 사용된 암호화 알고리즘 정보.
  2. Payload: 클라이언트/사용자에 대한 정보 (Claim 세트: ID, 만료시간 등). Base64로 인코딩되어 있으므로 누구나 복호화 가능 (민감 정보 저장 금지).
  3. Signature: Header + Payload + 서버의 Secret Key를 조합하여 위변조 여부를 검증하는 서명값.

🔄 JWT 로그인 흐름

  1. 로그인 성공 시 서버는 Secret Key로 서명된 JWT를 생성하여 클라이언트에 전달.
  2. 클라이언트는 토큰을 보관 (LocalStorage 또는 HttpOnly Cookie).
  3. 요청 시 Authorization: Bearer <JWT_TOKEN> 헤더에 담아 전송.
  4. 서버는 별도의 DB 조회 없이 Secret Key를 이용해 Signature만 검증하면 인증 완료.

⚖️ 세션 vs JWT 비교 Summary

구분세션 (Session)토큰 (JWT)
상태 저장 여부Stateful (서버에 상태 저장)Stateless (서버에 상태 저장 안 함)
정확한 제어서버에서 즉시 세션 강제 종료/만료 가능발급된 토큰은 만료 전까지 강제 정지 어려움
확장성다중 서버 환경 시 Redis 등 추가 세션 서버 필요서버 확장(Scale-Out) 시 별도 저장소 없이 검증 가능
데이터 크기쿠키에 ID만 들어가므로 작음Payload 정보에 따라 토큰 크기가 커질 수 있음

🛡️ 백엔드/보안 관점에서의 로그인 구현 체크리스트

  1. 비밀번호 저장:
  • 단방향 해시 함수(SHA-256 등) 단순 사용 금지.
  • Bcrypt, PBKDF2, Argon2 등 Salt(소금)가 적용된 Key Derivation Function 활용 필수.
  1. 세션 고정(Session Fixation) 공격 방어:
  • 로그인 성공 시 기존 세션 ID를 파기하고 새로운 세션 ID를 재발급하여 전달.
  1. 인증과 인가 분리:
  • 로그인 성공(인증) 후에도, 특정 API 호출 시 해당 사용자 권한(Role)이 맞는지 백엔드 인터셉터/미들웨어 단에서 인가(Authorization) 검증 필수.
  1. 쿠키 보안 설정:
  • 인증 쿠키에는 반드시 HttpOnly, Secure, SameSite=Lax/Strict 옵션 적용.
profile
파인애플 좋아하세요?

0개의 댓글