JWT 톺아보기

이강현·2023년 3월 19일
1
post-thumbnail

로그인 기능 구현에 많이 사용되고, 기술 면접 질문에도 자주 나오는 JWT에 대해 알아보겠습니다!


JWT는 무엇인가?

: JWT(JSON Web Token)는 개방형 표준(RFC 7519)으로, JSON 객체를 상호간에 안전하게 전송하기 위한 가볍고 자가수용적인(self-contained) signed 토큰입니다.

사용 목적

  1. Authorization: JWT를 사용하는 가장 흔한 시나리오입니다. 사용자가 로그인 하면, 서버는 서버는 유저의 정보에 기반한 토큰을 발급하여 전달합니다. 사용자는 서버에 요청할 때, JWT를 포함하여 해당 토큰으로 허용되는 서버의 서비스에 접근할 수 있습니다.
  2. 정보 교환: JWT는 정보를 안전하게 교환하는 좋은 방법입니다. 예를 들어, 공개키와 개인키 쌍을 사용해 JWT에 서명(sign)할 수 있으므로 발신자가 자신이 말하는 사람인지 확인할 수 있습니다. 또한 Header와 Payload를 사용해 서명이 계산되므로 정보가 변조되지 않았는지도 확인할 수 있습니다.

특징

  • JWT는 필요한 모든 정보를 자체적으로 지니고 있습니다. 즉, 자가수용적(self-contained)입니다.
    • 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위한 정보가 포함되어 있습니다.
    • 그러므로 데이터가 많아지면 토큰의 크기가 커지게 됩니다.
  • 세션과 달리 서버가 아닌 클라이언트에 정보가 저장되기 때문에, 메모리나 스토리지를 통해 세션을 관리했던 서버의 부담을 덜 수 있습니다.
    • JWT는 토큰을 클라이언트에 저장하고, 요청 시 토큰을 첨부하는 방식입니다.

구조

JWT는 JSON 데이터를 Base64URL Encode를 통해 인코딩하여 직렬화한 것입니다. Header, Payload, Signature로 구성되며, 각 요소는 . 으로 구분됩니다.

xxxxx.yyyyy.zzzzz

1. Header

: Header는 아래 두가지를 포함합니다.

  • alg: 서명(해싱) 알고리즘을 지정 (HMAC SHA256 or RSA)
  • typ: 토큰의 타입을 지정 (JWT)
{
  "alg": "HS256",
  "typ": "JWT"
}

2. Payload

: Payload는 여러 claims를 포함합니다.

하나의 claim은 정보의 한 조각(한 쌍의 name/value)을 의미합니다.

  • claims 종류
    • registed claims: 필수적이지 않지만 추천하는 미리 정의된 claims (주로 토큰에 대한 정보)
      • iss(issuer), exp(expiration time), sub(subject), aud(audience), and others
    • public claims: JWT를 사용하는 사람에 의해 정의될 수 있으나, 충돌 방지를 위해 IANA JSON Web Token Registry에 정의하거나, 충돌 방지 네임스페이스를 포함하는 URI로 정의
    • private claims: 상호간에 정보를 공유하기 위해 사용하는 커스텀 claims
{
  "sub": "1234567890",
  "name": "Alex",
  "admin": true
}

3. Signature

: Signature는 encoded header, encoded payload, 암호(secret)를 header에 지정된 알고리즘을 이용하여 생성됩니다.

  • 예를 들어, HMAC SHA256 algorithm을 사용한다면 아래 방식을 이용해 signature가 생성됩니다.
  • signature은 메시지가 도중에 변경되지 않았음을 확인하는 데 사용되며, 개인키(private key)로 서명된 토큰의 경우 JWT의 발신자가 누구인지도 확인할 수 있습니다.
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
  • Base64 Encode : 8비트 이진 데이터를 문자 코드에 영향을 받지 않는 공통 ASCII 영역의 문자들로만 이루어진 일련의 문자열로 바꾸는 인코딩 방식입니다. (원본 문자열 > ASCII binary> 6bit로 cut> base64 encodeing)

  • Base64URL Encode : Base64 Encode 기법을 여러 오류를 발생시키고, URL에 사용했을 떄 문제가 되는 62(+), 63(/)번 문자를 -, _ 로 변경한 기법입니다.

JWT 공식 홈페이지에서 쉽게 인코딩/디코딩 해볼 수 있으니 한번 연습해보세요:)

참고 자료

profile
함께하고 싶은 개발자, 이강현입니다:)

0개의 댓글