Home JWT (JsonWebToken)
Post
X

JWT (JsonWebToken)

JWT (JsonWebToken)에 대해 알아보자.


JWT (Json Web Token)

JWT (Json Web Token)이란 JSON 방식을 이용하여 정보를 저장하는 Claim 기반의 Web Token입니다.

JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것입니다.

Base64 URL-safe Encode 이란?
일반적인 Base64 Encode 에서 URL 에서 오류없이 사용하도록 ‘+’, ‘/’ 를 각각 ‘-‘, ‘_’ 로 표현한 것

주로 사용자의 인증(authentication) 또는 인가(authorization) 정보를 서버와 클라이언트 간에 안전하게 주고 받기 위해서 사용합니다.


JWT 구조

JWT는 . 을 기준으로 왼쪽부터 Header, Payload, Signature 세 가지 문자열로 나뉩니다.

jwt

  1. 헤더 (Header)
    typ, alg 로 구성됩니다.

    • typ : 토큰의 타입을 지정합니다. (JWT 등)
    • alg : 해시 알고리즘 방식을 지정하며, 서명 및 토큰 검증에 사용됩니다. (HS256, RSA 등)
    1
    2
    3
    4
    
    {
      "alg": "HS256",
      "typ": "JWT"
    }
    
  2. 페이로드 (Payload)
    사용할 정보의 조각들인 Claim이 담겨있습니다.

    Claim 이란?
    key-value 형식으로 이루어진 한 쌍의 정보를 Claim 이라고 합니다.

    1
    2
    3
    4
    5
    
    {
      "sub": "123456",
      "name": "Psmin",
      "iat": "1984513022"
    }
    
    • Claim 종류

      • Registered Claim : 미리 정의된 클레임

        iss - 발행자, exp - 만료시간, sub - 제목, iat - 발행 시간, jti - JWT ID

      • Public Claim : 사용자 정의 클레임으로, 공개용 정보를 위해 사용됩니다.

      • Private Claim : 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장합니다. (ex - “token_type” : access)

    1
    2
    3
    4
    5
    6
    
    {
      "jti": "1000", // Registered Claim
      "exp": "1521430000000", // Registered Claim
      "https://Psmin1994.github.io": true, // Public Claim
      "name": "Psmin" // Private Claim
    }
    
  3. 서명 (Signature)
    토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드입니다.

    SignatureHeaderPayload를 각각 BASE64Url로 인코딩한 값과 서버가 갖는 유일한 key 값을 합쳐 헤더에서 정의한 알고리즘으로 암호화한 것입니다.

    jwt-signature

    Header 와 Payload는 단순한 인코딩 값으로 제 3자가 복호화하거나 조작할 수 있지만, Signature는 서버의 비밀 Key를 알지 못하면 불가능합니다.
    따라서, Signature는 토큰의 위변조 여부를 확인하는데 사용합니다.


JWT 인증 과정

jwt-02

  1. 사용자가 ID와 Password를 입력하여 서버에 로그인 요청합니다.

  2. 서버는 회원 DB에 들어가 있는 사용자인지 확인합니다.

  3. 확인이 되면 Header, Payload, Signature를 정의한 후, secret key를 통해 JWT를 생성해 쿠키에 담아 클라이언트에 발급합니다.

  4. 클라이언트는 서버로부터 받은 JWT를 로컬 저장소에 저장한 후, API로 서버에 요청할 때 Authorization HeaderAccess Token을 담아서 보냅니다.

  5. 클라이언트가 Header에 담아서 보낸 JWT가 서버에서 발행한 토큰인지 일치 여부를 확인합니다.

  6. 일치한다면 인증이 통과되고 요청한 데이터를 응답합니다.

  7. 클라이언트가 서버에 요청할 때, Access Token의 시간이 만료되었다면 클라이언트는 Refresh Token을 이용해 Access Token 재발급을 요청합니다.

  8. 서버는 새로운 Access Token을 발급합니다.


Access Token / Refresh Token

JWT는 토큰 탈취의 위험성이 있기 때문에, Access Token, Refresh Token 으로 이중으로 나누어 인증을 하는 방식을 사용합니다.

  • Access Token
    클라이언트가 갖고있는 실제로 유저의 정보가 담긴 토큰입니다.
    즉, 서버에서 확인하여 사용자 정보에 맞게 응답을 진행합니다.
  • Refresh Token
    짧은 생명 주기를 갖는 Access Token을 재발급받기 위해 사용하는 토큰입니다.
    주로 데이터베이스에 사용자의 정보와 같이 저장합니다.

JWT 장단점

  • 장점

    • Header와 Payload로 Signature를 생성하기때문에 데이터 위변조 방지
    • 인증 정보에 대한 별도 저장소 불필요
    • 세션 방식은 클라이언트의 인증 정보를 저장하지만, JWT 방식은 Stateless한 무상태로 확장성이 우수
    • 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유 가능
    • 모바일 환경에서도 동작
    • DB 조회하지않으므로 서버 부하를 줄여줌
  • 단점

    • Self-contained
      토큰 자체에 정보를 담고 있으므로 양날의 검이 될 수 있습니다.
    • 토큰 길이
      토큰의 Payload에 3종류의 클레임을 저장하기 때문에, 정보가 많아질수록 토큰의 길이가 늘어나 네트워크에 부하를 줄 수 있습니다.
    • Payload 인코딩
      payload 자체는 암호화 된 것이 아니라 BASE64로 인코딩 된 것이기 때문에, 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있습니다.
    • Store Token
      stateless 특징을 가지기 때문에, 토큰은 클라이언트 측에서 관리하고 저장하기때문에 토큰 자체를 탈취당하면 대처하기가 어렵습니다.

참조

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.