세션 기반 인증, 토큰 기반 인증

dustle·2026년 5월 25일

HTTP는 왜 인증 방식이 필요한가

HTTP는 본래 무상태(stateless) 프로토콜입니다. 서버는 이전 요청을 기억하지 못합니다.
사용자가 로그인 후 다음 페이지로 이동하면 서버 입장에서는 그 사용자가 누구인지 알 수 없습니다.

이 문제를 해결하기 위해 서버가 "로그인된 사용자"라는 상태를 유지하는 방식이 필요했고, 그래서 세션과 토큰이 등장했습니다.

1. 세션

세션 기반 인증은 서버가 사용자 상태를 직접 저장하는 방식입니다.

동작 방식

  1. 사용자가 ID와 비밀번호로 로그인합니다.
  2. 서버는 인증에 성공하면 세션 ID를 생성하고 서버 메모리(또는 Redis 같은 저장소)에 저장합니다.
  3. 서버는 클라이언트에게 세션 ID를 쿠키로 전달합니다.
  4. 이후 모든 요청에서 브라우저는 자동으로 쿠키를 함께 보냅니다.
  5. 서버는 쿠키에 담긴 세션 ID로 저장소를 조회하여 사용자를 식별합니다.

장점

  • 서버에서 세션을 직접 관리하므로 강제 로그아웃이 쉽습니다.
  • 세션 ID 자체에는 의미가 없어 노출되어도 정보 유출이 적습니다.
  • 구현이 비교적 단순하고 검증된 방식입니다.

단점

  • 서버가 모든 세션을 저장해야 하므로 사용자가 많아지면 메모리 부담이 커집니다.
  • 서버 확장 시 세션을 공유할 별도 저장소가 필요합니다.
  • 모바일 앱이나 외부 API와 연동할 때 쿠키 기반이라 처리하기 번거롭습니다.

2. 토큰

토큰 기반 인증은 서버가 상태를 저장하지 않고, 클라이언트가 인증 정보를 토큰 형태로 들고 다니는 방식입니다. 대표적으로 JWT(JSON Web Token)가 있습니다.

동작 방식

  1. 사용자가 ID와 비밀번호로 로그인합니다.
  2. 서버는 인증 성공 시 토큰을 생성하여 클라이언트에게 전달합니다.
  3. 클라이언트는 토큰을 로컬 스토리지나 쿠키에 저장합니다.
  4. 이후 요청 시 Authorization 헤더에 토큰을 담아 전송합니다.
  5. 서버는 토큰의 서명을 검증하여 사용자를 식별합니다.

장점

  • 서버가 상태를 저장하지 않아 확장에 유리합니다.
  • 토큰 안에 사용자 정보가 있어 별도 조회가 필요 없습니다.
  • 모바일, 웹, 외부 서비스 등 다양한 클라이언트에서 사용하기 좋습니다.

단점

  • 한번 발급된 토큰은 만료 전까지 무효화하기 어렵습니다.
  • 토큰에 정보가 담겨 있어 길이가 길고 매 요청마다 전송 부담이 있습니다.
  • 토큰이 탈취되면 만료 전까지 그대로 사용될 수 있습니다.

3. 세션 기반 인증의 보안 고려사항

3.1 세션 하이재킹

공격자가 세션 ID를 탈취하여 사용자를 가장하는 공격입니다. HTTPS를 적용하여 통신 구간에서 세션 ID가 노출되지 않도록 해야 합니다.

3.2 CSRF (Cross-Site Request Forgery)

사용자가 로그인된 상태에서 악의적인 사이트에 접속하면, 그 사이트가 사용자 권한으로 요청을 보내는 공격입니다. 쿠키가 자동으로 전송되는 특성을 악용합니다.

대응 방법

  • CSRF 토큰을 발급하여 요청마다 검증합니다.
  • SameSite 쿠키 속성을 Strict 또는 Lax로 설정합니다.
  • 중요한 요청은 재인증을 요구합니다.

3.3 세션 고정 공격

공격자가 미리 발급받은 세션 ID를 피해자가 사용하도록 유도하는 공격입니다. 로그인 성공 후 반드시 새로운 세션 ID를 발급해야 합니다.

3.4 쿠키 보안 속성

쿠키에는 다음 속성을 반드시 설정해야 합니다.

  • HttpOnly: 자바스크립트에서 쿠키 접근을 차단하여 XSS 피해를 줄입니다.
  • Secure: HTTPS 통신에서만 쿠키를 전송합니다.
  • SameSite: 크로스 사이트 요청에서 쿠키 전송을 제한합니다.

4. 토큰 기반 인증의 보안 고려사항

4.1 XSS (Cross-Site Scripting)

토큰을 로컬 스토리지에 저장하면 자바스크립트로 접근이 가능하므로 XSS 공격에 취약합니다. 사용자 입력값에 대한 적절한 이스케이프 처리가 필수입니다.
HttpOnly 쿠키에 토큰을 저장하는 방식도 고려할 수 있습니다.

4.2 토큰 탈취와 만료 관리

토큰이 탈취되면 만료 전까지 그대로 사용될 수 있습니다. 이를 완화하기 위해 다음을 고려합니다.

  • Access Token의 만료 시간을 짧게 설정합니다 (예: 15분~1시간).
  • Refresh Token을 별도로 발급하여 Access Token을 재발급합니다.
  • Refresh Token은 더 안전한 곳에 저장하고 만료 시간을 길게 설정합니다.

4.3 서명 검증

토큰의 서명 알고리즘과 비밀키 관리가 중요합니다.

  • 비밀키는 충분히 길고 복잡해야 하며 외부에 노출되면 안 됩니다.
  • 알고리즘을 None으로 설정하는 공격을 막기 위해 서버에서 허용 알고리즘을 명시합니다.
  • 가능하면 비대칭 키 방식(RS256)을 사용합니다.

4.4 민감 정보 미포함

JWT의 Payload는 Base64로 인코딩될 뿐 암호화되지 않습니다. 따라서 비밀번호나 주민번호 같은 민감 정보를 절대 포함하면 안 됩니다.

4.5 토큰 무효화 전략

발급된 토큰을 즉시 무효화하기 어렵다는 단점을 보완하기 위해 다음 방법을 사용합니다.

  • 블랙리스트를 운영하여 무효화된 토큰을 별도로 관리합니다.
  • 짧은 만료 시간과 Refresh Token 조합으로 노출 시간을 최소화합니다.
  • 비밀번호 변경이나 로그아웃 시 모든 Refresh Token을 폐기합니다.

0개의 댓글