안전하고 효율적인 웹 인증, JWT 완벽 가이드

JSON Web Token의 동작 원리부터 실제 활용까지

Posted by ChaelinJ on November 01, 2025

서론: 웹 인증의 새로운 패러다임, JWT

현대의 웹 애플리케이션은 사용자 경험과 확장성을 최우선으로 합니다. 이러한 요구사항 속에서 기존 세션 기반 인증 방식의 한계는 더욱 명확해지고 있죠. 서버의 상태를 유지해야 하는 세션 방식은 서버 확장에 어려움이 있고, 모바일 환경이나 마이크로서비스 아키텍처에서는 더욱 비효율적입니다.

이러한 문제에 대한 우아하고 강력한 해결책으로 등장한 것이 바로 JSON Web Token (JWT) 입니다. JWT는 클라이언트와 서버 간의 통신에서 정보를 안전하게 주고받기 위해 정의된 오픈 표준입니다. 이번 포스팅에서는 JWT가 무엇인지, 어떻게 동작하며, 실제 프로젝트에서 어떻게 활용할 수 있는지 깊이 있게 알아보겠습니다.

본문: JWT의 이해와 활용

JWT란 무엇인가?

JWT는 클레임(Claim)을 표현하는 URL-safe한 방법입니다. 여기서 클레임은 사용자 정보, 권한 등의 데이터를 의미합니다. JWT는 세 부분으로 구성되며, 각 부분은 점(.)으로 구분됩니다.

  1. Header (헤더): 토큰의 타입(typ)과 서명에 사용된 알고리즘(alg)을 명시합니다.
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  2. Payload (페이로드): 실제 정보를 담는 부분으로, “클레임”이라고 불리는 이름/값 쌍으로 구성됩니다. 사용자 ID, 권한, 토큰 만료 시간(exp) 등이 포함될 수 있습니다. 페이로드는 암호화되지 않으므로, 민감한 정보는 담지 않는 것이 중요합니다.
    {
      "sub": "1234567890",
      "name": "John Doe",
      "iat": 1516239022,
      "exp": 1516242622
    }
    
  3. Signature (서명): 헤더와 페이로드를 Base64Url로 인코딩한 값과 서버의 비밀 키(Secret Key)를 사용하여 암호화 알고리즘으로 생성합니다. 이 서명은 토큰의 위변조 여부를 검증하는 데 사용됩니다.
    HMACSHA256(
      base64UrlEncode(header) + "." +
      base64UrlEncode(payload),
      secret
    )
    

이 세 부분이 각각 Base64Url로 인코딩된 후 점으로 연결되면 최종 JWT 문자열이 완성됩니다.

JWT 인증 과정

JWT를 활용한 인증은 다음과 같은 흐름으로 진행됩니다.

  1. 사용자 로그인: 클라이언트(브라우저 또는 앱)가 사용자 ID와 비밀번호로 로그인 요청을 보냅니다.
  2. 토큰 발급: 서버는 사용자 정보를 확인하고, 유효한 사용자라면 JWT를 생성하여 클라이언트에게 응답으로 전송합니다.
  3. 토큰 저장: 클라이언트는 전달받은 JWT를 로컬 저장소(localStorage, sessionStorage, cookies 등)에 저장합니다.
  4. 인증 요청: 클라이언트가 보호된 리소스에 접근할 때는, 저장된 JWT를 HTTP 요청 헤더의 Authorization 필드에 Bearer 스키마와 함께 포함하여 보냅니다.
    Authorization: Bearer <your_jwt_token_here>
    
  5. 토큰 검증: 서버는 요청을 받으면 JWT의 서명을 검증하고, 페이로드의 정보를 통해 사용자를 인증 및 인가합니다. 서명이 유효하다면 토큰의 내용이 위변조되지 않았음을 확신할 수 있습니다.

JWT의 장점과 고려사항

장점:

  • Stateless (무상태): 서버가 사용자 세션 정보를 저장할 필요가 없어 서버 확장이 용이하고, 로드 밸런싱에 유리합니다.
  • Self-contained (자가 포함적): 토큰 자체에 사용자 정보와 권한이 포함되어 있어, 서버는 데이터베이스 조회 없이 토큰만으로 사용자 정보를 파악할 수 있습니다.
  • Cross-Domain (교차 도메인): 여러 도메인 간의 인증을 쉽게 처리할 수 있습니다.
  • Compact: 토큰의 크기가 작아 HTTP 헤더를 통해 효율적으로 전송됩니다.

고려사항 및 보안:

  • 토큰 탈취 위험: JWT는 Base64Url 인코딩될 뿐, 암호화되는 것이 아닙니다. 페이로드에 민감한 정보를 직접 담지 않아야 합니다. 토큰이 탈취될 경우, 만료되기 전까지는 권한이 도용될 수 있습니다.
  • 만료 처리: 토큰의 유효 기간을 짧게 설정하고, Refresh Token을 함께 사용하여 보안을 강화할 수 있습니다.
  • 토큰 저장 위치: XSS(Cross-Site Scripting) 공격에 취약할 수 있으므로, localStorage보다는 HttpOnly 쿠키 사용을 고려하는 것이 좋습니다.
  • 취소(Revocation)의 어려움: 한 번 발급된 JWT는 만료 시점까지 유효하므로, 중간에 강제로 만료시키기 어렵습니다. 블랙리스트 구현 등을 통해 해결할 수 있으나, Stateless의 장점을 일부 희생하게 됩니다.

결론: JWT, 현명한 선택을 위한 이해

JWT는 분산 환경과 마이크로서비스 아키텍처에 매우 적합한 강력한 인증 방식입니다. 무상태성 덕분에 서버 자원을 효율적으로 사용하고 확장성을 높일 수 있습니다. 하지만 JWT의 동작 원리와 보안 취약점을 정확히 이해하고 올바르게 구현하는 것이 중요합니다.

페이로드에 담는 정보의 종류, 토큰의 만료 주기, 그리고 토큰을 어디에 저장할 것인지 등 다양한 측면을 신중하게 고려하여 안전하고 효율적인 인증 시스템을 구축하시길 바랍니다. JWT에 대한 깊이 있는 이해는 여러분의 서비스 보안을 한층 더 강화하는 중요한 밑거름이 될 것입니다.

Text by Chaelin & Gemini. Photographs by Chaelin, Unsplash.