JWT(Json Web Token)

✒️ 2025-05-16 09:07 내용 수정


두 시스템 간의 정보를 안전하게 주고받기 위해 JSON 형식으로 인코딩 된 형식


JWT를 사용하는 경우

  1. Authorization(인가) : 사용자가 로그인하면 각각의 다음 요청은 JWT를 포함하여 사용자가 토큰으로 허용된 라우트, 서비스, 자원에 접근할 수 있다.
    • Single Sign On은 요즘 JWT를 널리 사용하는 기능으로, 작은 오버헤드와 서로 다른 도메인 간에 쉽게 사용할 수 있다.
  2. 정보 교환 : JWT는 주체 간의 정보를 안전하게 교환할 수 있는 방법이다.
    • JWT는 public/private key 쌍과 같이 서명될 수 있기 때문에 정보를 보낸 주체가 누구인지 확신할 수 있다.
    • 추가적으로 서명은 헤더와 payload를 사용하여 계산되기 때문에 컨텐츠가 변조되지 않았음을 확인할 수 있다.

구조

# Header.Payload.Signature
  xxxxxx.yyyyyy.zzzzzz

jwt 1.png

1. Header

{
	"alg": "HS256", // 서명에 사용된 알고리즘
	"typ": "JWT" // 토큰 타입
}

2. Payload

  1. Registered claims(표준 클레임) : 유용하고 상호 운용 가능한 클레임을 제공하기 위해 사전 정의된 클레임들의 모음으로, 필수는 아니지만 권장된다.

    • iss(issuer), exp(expiration time), sub(subject), aud(audience) 등이 있다.
    • JWT는 간결해야 하기에 클레임 이름은 3글자로만 되어 있다.
  2. Public claims(공개 클레임) : JWT를 사용하는 사람들이 정의할 수 있는 클레임이다.

    • 충돌을 피하기 위해 IANA JSON Web Token Registry나 충돌을 방지할 수 있는 네임 스페이스를 포함하는 URI로 정의해야 한다.
  3. Private claims(비공개 클레임) : 클레임 사용을 동의한 주체 간의 정보를 공유하기 위해 생성된 커스텀 클레임으로, 이 클레임은 표준 클레임도 공개 클레임도 아니다.

{
	"sub": "1234567890", // subject
	"name": "John Doe", // 이름
	"iat": 1516239022 // issued at
}

3. Signature

HMACSHA256(
	base64UrlEncode(header) + "." +
	base64UrlEncode(payload),
)

JWT 사용 시 주의 사항

  1. Authentication(인증)에서 사용자가 credentials(자격 증명)을 사용하여 성공적으로 로그인하면 JWT가 반환 된다.
    • 이 토큰은 credential(자격 증명)이므로, 보안 문제를 방지하기 위해 큰 주의를 기울여야 하며, 일반적으로 토큰을 필요 이상으로 보관하지 않는 것이 좋다.
    • 기한이 지난 토큰을 가지고 있으면 보안 상 문제가 커질 수 있어 토큰의 수명을 제한하는 것이 좋다.
  2. 또한 브라우저 저장소는 보안이 취약하기에 민감한 session 데이터를 브라우저 저장소에 저장하지 말아야 한다.
    • 애플리케이션에 필요한 인증은 데이터가 저장된 장치의 로컬 권한을 통해 사용자가 우회할 수 있어 민감한 정보를 로컬 저장소에 저장하는 것은 피해야 한다.
    • 브라우저 보안 보장으로 인해 데이터에 접근하는 것이 인증이나 인가가 아닌 경우에 로컬 저장소를 사용하는 것이 적절하다.
    • 참고 자료 : HTML5 Security Local Storage
  3. 사용자가 보호된 라우트나 자원에 접근하고자 할 때 사용자 에이전트는 Authorization headerBearer schema를 사용하여 JWT를 전송해야 한다.
Authorization: Bearer <token>
  1. HTTP header를 사용하여 JWT를 전송하면 JWT가 너무 커지지 않도록 조심해야 한다.

    • 일부 서버는 header에 8 KB을 받지 못한다.
    • JWT에 너무 많은 정보를 넣는 대신에 Auth0 Fine-Grained Authorization과 같은 방법으로 대체하는 것이 좋다.
  2. 토큰이 Authorization header에 담겨 보내질 경우, Cross-Origin Resource Sharing(CORS)은 쿠키를 사용하지 않는 한 문제를 일으키지 않는다.

  3. 서명된 토큰을 사용할 경우 토큰에 있는 정보는 다른 사용자나 주체에게 노출될 수 있으며, 다른 사용자나 주체는 이 정보를 변경할 수 없다.

    • 따라서 비밀 정보는 토큰 안에 포함되어선 안된다.

JWT 획득 및 자원 접근 과정

  1. 애플리케이션이나 클라이언트가 Authorization 서버에 (Authorization)인가를 요청한다.
  2. Authorization(인가)가 허가되면 Authorization 서버에선 애플리케이션/클라이언트로 자원 서버에 접근할 수 있는 접근 토큰을 전송한다.
  3. 애플리케이션/클라이언트가 접근 토큰을 사용하여 자원 서버에 API와 같은 보호된 자원에 접근한다.