애플리케이션 개발의 Session Token — 정의, 작동 원리 및 JWT와의 차이점

저자: IT Sectr 게시일: 2026-04-05 읽는 시간: 9 분

Session Token은 사용자 인증 성공 후 서버가 생성하고 후속 요청을 식별하는 데 사용하는 고유 식별자입니다. 자체 포함 토큰(JWT)과 달리 session token은 그 자체로 데이터를 포함하지 않는 임의의 문자열입니다. 모든 세션 정보는 서버의 RAM 또는 데이터베이스에 저장됩니다. OAuth.com, 2025에 따르면 session token은 서버사이드 웹 애플리케이션과 하이브리드 모바일 아키텍처에서 가장 일반적인 인증 메커니즘으로 남아 있습니다.

핵심 사항

  • Session Token — 서버사이드 세션 데이터를 참조하는 임의의 식별자
  • Stateful — 서버가 Redis, Memcached 또는 데이터베이스에 세션 상태를 저장
  • 간편한 취소 — 서버에서 세션 레코드를 삭제하기만 하면 토큰이 무효화됨
  • 보안 — 데이터가 토큰에 저장되지 않아 디코딩을 통한 유출 방지
  • 쿠키 — HttpOnly, Secure 및 SameSite 플래그와 함께 웹 애플리케이션에서 session token을 전송하는 전통적인 방식

Session Token이란?

Session Token(세션 식별자)은 사용자 인증 후 서버가 생성하여 세션 데이터와 연결하는 고유한 문자열입니다. 토큰에는 사용자 정보가 포함되지 않습니다 — 이는 단지 서버에 저장된 데이터의 키일 뿐입니다. 이 접근 방식을 stateful 인증이라고 합니다. 서버는 각 활성 세션의 상태를 저장하고 모든 요청에서 이를 확인합니다.

세션 데이터에는 다음이 포함됩니다: 사용자 ID, 로그인 시간, IP 주소, user-agent, 권한 목록, 마지막 활동 시간. 클라이언트가 session token과 함께 요청을 보내면 서버는 세션 저장소에서 해당 레코드를 찾고, 유효성을 확인하며, 요청 처리를 위해 데이터를 검색합니다. 세션 레코드가 없거나 만료된 경우 서버는 인증 오류를 반환하고 다시 로그인하도록 요구합니다.

OWASP, 2025에 따르면 session token은 즉각적인 액세스 취소가 필요한 애플리케이션의 표준으로 남아 있습니다 — 예를 들어 관리자가 사용자 세션을 즉시 종료할 수 있어야 하는 은행 시스템 및 기업 포털에서 그렇습니다. 이러한 시스템에서 session token은 추가 차단 메커니즘 없이는 stateless 토큰으로는 달성할 수 없는 완전한 액세스 제어를 제공합니다.

Session Token 작동 방식

프로세스는 클라이언트가 인증 서버에 자격 증명을 보내면서 시작됩니다. 서버는 로그인과 비밀번호를 확인하고, 저장소(일반적으로 Redis 또는 데이터베이스)에 세션 레코드를 생성하며, 클라이언트에 고유한 session token을 반환합니다. 클라이언트는 토큰을 저장하고 이후 모든 요청과 함께 전송하며, 서버는 매번 세션의 존재와 유효성을 확인합니다.

서버 세션 및 저장소

Redis는 인메모리 저장소와 TTL(수명 시간) 지원 덕분에 가장 인기 있는 세션 저장소입니다. 각 세션은 키-값 쌍으로 저장되며, 키는 session token이고 값은 세션 데이터가 포함된 JSON 객체입니다. TTL은 만료된 세션을 자동으로 제거합니다. 대안: Memcached(메모리 전용, 디스크 지속성 없음), PostgreSQL/MySQL(지속적이지만 느림), DynamoDB(AWS 인프라용).

Redis의 세션 구조 예: session:{token}{“userId”: 42, “role”: “admin”, “createdAt”: 1812345678, “lastAccess”: 1812345678}. 서버는 각 요청에서 lastAccess를 업데이트하여 비활성 시간 제한을 구현할 수 있습니다 — 비활성 기간 후 자동 세션 종료.

쿠키 vs 헤더

Session Token은 HTTP 쿠키 또는 Authorization HTTP 헤더를 통해 두 가지 방식으로 전송할 수 있습니다. 쿠키는 웹 애플리케이션의 전통적인 방식입니다. 서버는 HttpOnly(JavaScript에서 액세스 불가), Secure(HTTPS 전용), SameSite(CSRF 보호) 플래그와 함께 쿠키를 설정합니다. 모바일 애플리케이션의 경우 네이티브 클라이언트에서 쿠키 메커니즘이 항상 편리하지 않기 때문에 Authorization: Bearer <session_token> 헤더가 더 일반적으로 사용됩니다.

Session Token 수명 주기

Session Token의 수명 주기는 생성, 활성 세션 유지, 종료의 세 단계로 구성됩니다. 각 단계에서는 토큰 유출 또는 가로채기를 방지하기 위한 적절한 보안 구성이 필요합니다.

생성, 저장 및 삭제

생성 — 서버는 128~256비트의 암호학적으로 안전한 임의 문자열을 생성합니다(예: Java의 SecureRandom 또는 Python의 os.urandom 사용). 토큰은 예측 불가능해야 합니다 — 엔트로피 없는 UUID 또는 타임스탬프 사용은 허용되지 않습니다. 저장은 클라이언트에서: iOS에서는 Keychain, Android에서는 EncryptedSharedPreferences, 웹에서는 HttpOnly 쿠키. 삭제는 로그아웃 시 발생합니다. 클라이언트는 저장소에서 토큰을 제거하고, 서버는 Redis에서 세션 레코드를 삭제합니다. 로그아웃 후 session token은 무용지물이 됩니다 — 서버는 해당 레코드를 찾을 수 없습니다.

SANS Institute, 2025에 따르면 적절한 세션 종료 구현(서버사이드 정리와 함께 로그아웃)은 도난된 토큰을 사용한 공격의 최대 70%를 방지합니다. 클라이언트에서 토큰을 삭제하는 것뿐만 아니라 서버에서 세션을 무효화하는 것이 중요합니다.

Session Token vs JWT

Session Token과 JWT는 두 가지 다른 인증 접근 방식을 나타냅니다. Session Token은 stateful(서버가 상태 저장), JWT는 stateless(데이터가 토큰 내부)입니다. 둘 중 선택은 애플리케이션 아키텍처와 보안 요구 사항에 따라 다릅니다.

기준Session TokenJWT
모델Stateful(서버에 데이터)Stateless(토큰 내 데이터)
취소즉시 — Redis에서 세션 삭제블랙리스트 또는 짧은 TTL 필요
크기16~64바이트500~2000바이트
데이터 저장서버 전용(안전함)토큰 내부(base64, 암호화되지 않음)
확장공유 저장소(Redis) 필요필요 없음 — 토큰이 로컬에서 검증됨
CSRF 보호SameSite 쿠키 + CSRF 토큰 필요필요 없음(토큰이 헤더에 있음)

Session Token을 선택해야 하는 경우

Session Token은 다음과 같은 경우에 선호됩니다: 즉각적인 세션 취소가 필요한 경우(은행, 관리 패널), 애플리케이션이 공유 Redis와 함께 하나 이상의 서버에서 실행되는 경우, 세션 데이터가 커서 JWT에 맞지 않는 경우, 또는 팀이 토큰 디코딩을 통한 데이터 유출 위험을 최소화하려는 경우. 이러한 시나리오에서 session token은 의심스러운 활동 시 즉각적인 액세스 차단을 제공합니다 — Redis에서 하나의 레코드만 삭제하면 사용자의 모든 세션이 무효화됩니다.

Redis, 2025에 따르면 세션 키 수준에서 TTL(EXPIRE 명령)을 사용하면 백그라운드 작업에 오버헤드 없이 만료된 세션을 자동으로 정리합니다. TTL이 1시간이고 동시 사용자 10,000명의 부하가 있는 세션의 경우 Redis는 1KB 세션 크기에서 약 1GB의 RAM을 소비하므로 대부분의 애플리케이션에서 비용 효율적입니다.

Session Token 보안

Session Token의 보안은 두 가지 원칙에 기반합니다: 토큰은 예측 불가능해야 하며 전송 및 저장 중에 보호되어야 합니다. 주요 위협은 토큰 가로채기(man-in-the-middle, XSS), 예측(취약한 생성), 세션 고정(session fixation)입니다.

토큰 도난 방지

보호에는 다음이 포함됩니다: 토큰이 포함된 모든 요청에 HTTPS 사용, 짧은 세션 TTL 설정(15~60분 비활성), IP 및 user-agent에 세션 바인딩(각 요청 시 추가 확인), 쿠키에 Secure 및 HttpOnly 플래그 사용, 민감한 작업(비밀번호 변경, 권한 상승) 후 정기적인 session token 교체. OWASP는 또한 로그인 후 새 세션을 만들 때 이전 세션을 무효화하는 세션 관리 구현을 권장합니다 — 이는 세션 고정을 방지합니다.

OWASP ASVS, 2025에 따르면 세션은 최소 두 가지 요소에 바인딩되어야 합니다: 토큰 자체(클라이언트가 가진 것)와 IP/user-agent(서버가 아는 것). 이러한 요소가 일치하지 않으면 서버는 세션을 종료하고 재인증을 요구해야 합니다.

Kotlin 구현 예제

다음은 Spring Boot와 Redis를 사용한 Kotlin의 서버사이드 session token 구현 예제입니다. 서버는 SecureRandom을 통해 암호학적으로 안전한 토큰을 생성하고, TTL과 함께 Redis에 세션을 저장하며, 각 요청에서 이를 검증합니다. 코드는 세 가지 주요 작업을 보여줍니다: 세션 생성, 검증 및 무효화.

kotlin
data class Session(
    val userId: Long,
    val role: String,
    val createdAt: Long,
    val lastAccess: Long
)

object SessionManager {
    private val redis = JedisPool("localhost", 6379)

    fun createSession(userId: Long, role: String): String {
        val token = generateSecureToken()
        val session = Session(userId, role, now(), now())
        redis.resource.use { conn ->
            conn.setex("session:$token", 3600, toJson(session))
        }
        return token
    }

    fun validateSession(token: String): Session? {
        redis.resource.use { conn ->
            val json = conn.get("session:$token") ?: return null
            return fromJson(json)
        }
    }

    fun invalidateSession(token: String) {
        redis.resource.use { it.del("session:$token") }
    }

    private fun generateSecureToken(): String {
        val bytes = ByteArray(32)
        SecureRandom().nextBytes(bytes)
        return Base64.getUrlEncoder().withoutPadding().encodeToString(bytes)
    }
}

이 구현은 Redis에 대한 스레드 안전 연결을 위해 JedisPool을 사용합니다. createSession 메서드는 1시간(3600초)의 TTL을 설정합니다 — 이 기간 후 Redis는 자동으로 레코드를 삭제합니다. validateSession 메서드는 존재하지 않거나 만료된 세션에 대해 null을 반환하여 서버가 유효하지 않은 토큰이 있는 요청을 올바르게 처리하고 HTTP 401을 반환할 수 있게 합니다.

자주 묻는 질문

Session token과 access token의 차이는 무엇인가요?

Session token은 서버사이드 세션 식별자(stateful)입니다. Access token은 API 액세스를 위한 자격 증명(JWT 또는 opaque 가능)입니다. Session token은 일반적으로 웹 세션에 사용되며, access token은 모바일 및 SPA 애플리케이션의 API 요청에 사용됩니다. 둘은 공존할 수 있습니다: 웹용 session token, API용 access token.

XSS 공격으로부터 session token을 보호하는 방법은?

주요 보호 방법은 세션 토큰이 포함된 쿠키에 HttpOnly 플래그를 설정하는 것입니다. 이 플래그는 JavaScript에서 쿠키에 액세스하는 것을 차단하여 XSS 공격이 토큰을 도난하는 데 무용지물이 되게 합니다. 또한 SameSite=Strict 플래그는 쿠키가 교차 사이트 요청과 함께 전송되는 것을 방지하여 CSRF로부터 보호합니다.

Session token의 수명은 얼마나 되어야 하나요?

두 가지 시간 제한이 권장됩니다: 절대 시간 제한(8~24시간 — 최대 세션 수명)과 상대 시간 제한(15~30분 비활성 — 이후 세션 종료). 은행 애플리케이션의 경우 절대 시간 제한이 1~2시간으로 단축되며, 이메일 클라이언트의 경우 7일까지 가능합니다.

세션 고정(session fixation)이란 무엇인가요?

Session fixation은 공격자가 사용자에게 알려진 세션 식별자를 사용하도록 강제하는 공격입니다. 보호: 인증 성공 후 서버는 클라이언트가 전달한 토큰을 계속 사용하는 대신 새로운 session token을 생성해야 합니다. 이전 토큰은 출처에 관계없이 무효화되어야 합니다.

REST API에서 session token을 사용할 수 있나요?

, 클라이언트가 Authorization 헤더(쿠키 아님)로 전송하는 경우 session token은 REST API에 적합합니다. 모바일 애플리케이션의 경우 이는 일반적인 관행입니다. 단점: 여러 서버로 확장할 때 공유 세션 저장소(Redis)가 필요하여 아키텍처에 단일 장애 지점이 추가됩니다.

요약

  • Session Token — 서버사이드 세션 데이터를 참조하는 stateful 식별자
  • 장점 — 즉각적인 취소 및 서버에서 세션에 대한 완전한 제어
  • 저장소 — 자동 정리를 위한 TTL이 있는 Redis, Memcached 또는 데이터베이스
  • 보안 — SecureRandom 생성, HTTPS, HttpOnly + SameSite 쿠키
  • Session vs JWT — Session은 취소가 쉽고, JWT는 확장이 쉬움
  • 시간 제한 — 절대(8~24시간) 및 상대(15~30분 비활성)
  • 세션 고정 — 로그인 후 새 토큰을 생성하여 방지

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기