WEEK 6-9: Spring JWT

ensalada.de.pollo·2025년 5월 18일

be

목록 보기
31/44

Token

Token은 Web Application이나 API에서 인증(Authentication)과 인가(Authorization)에 사용되는 디지털 문자열입니다. 사용자의 신원과 권한을 증명하고, 요청의 유효성을 검증하는 역할을 합니다. 인증된 사용자임을 확인하기 위한 고유한 서명을 포함하기 때문에 위조된 요청인지도 확인할 수 있습니다.

cookie처럼 서버가 아닌, 클라이언트에 저장이 되며, 서버는 토큰의 유효성만 검증합니다.

동작 원리

사용자가 아이디/비밀번호 등 자격 정보를 서버에 보내 로그인을 요청합니다. 여기서 서버는 DB등에서 자격 정보를 확인하고, 검증에 성공하면 토큰을 생성해 클라이언트에 전달합니다. 토큰에는 사용자 정보, 만료 시간, 서명 등이 포함되어있습니다.

클라이언트는 토큰을 안전하게(HttpOnly cookie, localStorage, Secure Storage 등) 저장합니다. 이후 모든 요청의 Authorization 헤더 등에 토큰을 포함하여 서버에 전달합니다.

서버는 토큰의 서명, 만료, 권한 등을 검증한 후 요청을 처리합니다. 만약, 토큰이 만료되면 refresh token 등으로 재발급하거나 재로그인이 필요하게 됩니다.

장점과 단점

장점

  • Stateless하기 때문에 확장성이 뛰어납니다.
  • 웹, 모바일, IoT 등 다양한 클라이언트에서 사용이 가능합니다.
  • token 자체에 서명이 존재하기 때문에 위조나 변조를 방지할 수 있습니다.
  • 서버 간 인증, SSO, OAuth 등과 연동이 쉽습니다.

단점

  • 세션 및 쿠키 방식보다 데이터의 용량이 커 트래픽이 증가합니다.
  • 사용자의 정보 등이 들어가는 Payload 부분은 인코딩만 되어있고 암호화는 되어있지 않아 민감 정보를 저장할 수 없습니다.
  • 탈취된다면 만료 전까지 악용이 가능하기 때문에, 짧은 만료시간이 필요합니다.

JWT(JSON Web Token)

인증에 필요한 정보를 JSON 포맷으로 담고 서명까지 포함해 하나의 문자열로 만든 토큰입니다.

구조

Header.Payload.Signature와 같은 구조를 가지고 있으며, 각각이 Base64Url로 인코딩 되어있고, 점(.)으로 구분됩니다.

구조설명
Header토큰 타입(JWT)와 서명 알고리즘(HS256, RS256 등)
Payload실제 인증/인가 정보(Claims), 사용자 정보, 권한, 만료시간 등
SignatureHeader와 Payload를 서버의 Secret Key로 서명

Payload - Claims의 종류

  • Registered Claims
    • iss(issuer): 발행자
    • exp(expiration time): 만료 시간
    • sub(subject): 제목
    • iat(issued At): 발생 시각
    • jti(JWT ID): 토큰의 고유 식별자
  • Public Claims
    공개용 정보 전달 목적으로, 충돌 방지가 필요함
  • Private Claims
    당사자들 간 정보를 공유하기 위한 목적

동작 예시

서버가 로그인 성공시 JWT를 생성합니다. 클라이언트는 JWT를 저장하며, API 요청 시 Authorization 헤더에 JWT를 포함(Bearer {JWT}와 같은 방식)합니다.

서버는 클라이언트로부터 받은 JWT의 서명, 만료, 권한 등을 검증 후 처리합니다.

주의점

Header와 Payload는 누구나 디코딩이 가능하므로 민감 정보는 저장하면 안됩니다. Singature와 같은 경우는 서버의 Secret Key로 생성하며 변조 시 서버가 검증에 실패합니다.

Secret Key는 충분히 복잡하고 안전하게 관리해야 합니다.

토큰이 탈취될 우려가 있으므로 HTTPS를 사용, HttpOnly/Secure 쿠키, 짧은 만료시간, Refresh Token의 활용 등이 필요합니다.

유효성 검사

Signature부분을 Secret Key로 재계산하여 일치 여부를 확인할 수 있습니다. 이 경우, 만료 시간과 위변조 여부 등을 검증할 수 있으며, 검증 통과시 인증이 성공하고 요청을 처리합니다.

Secret Key로 재계산하기 때문에, secret key가 노출되지 않는 이상, 서버만이 올바른 Signature를 생성할 수 있습니다.

중요한 것은 JWT의 목적은 정보 보호가 아닌, 위조 방지입니다. 그렇기 때문에 Payload에는 절대로 민감 정보를 저장하면 안됩니다.

Access Token과 Refresh Token

Access Token은 인증된 사용자의 정보와 권한이 담긴 토큰입니다. 탈취에 대응하기 위한 목적으로 유효 기간이 보통 짧습니다. API 요청시 Authorization 헤더에 포함하여 요청을 보냅니다.

Refresh Token의 경우, 유효 기간이 보다 짧은 Access Token이 만료되었을 때 재발급을 받기 위해 존재하는 토큰입니다. 그렇기 때문에 유효 기간이 Access Token 보다 깁니다. 보통 데이터베이스에 유저 정보와 같이 저장을 하게 됩니다.

하지만 Refresh Token의 경우에도 탈취의 우려가 있으므로, 토큰 재발급 횟수에 제한을 두거나 Refresh Token Rotation을 사용해 탈취를 예방하는 방법을 생각하며 JWT를 사용해야 합니다.

자료 및 코드 출처: 스파르타 코딩클럽

0개의 댓글