ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Json Web Token
    기술 면접/Spring 2022. 4. 30. 18:59

     JSCode 스터디가 끝나고 평소에 공부했던 안드로이드와 연결을 시도해보려 했다. 스터디에서 진행한 프로젝트는 Spring Security를 활용해 로그인을 구현했는데, 안드로이드에서 로그인으로 권한을 취득하려면 JWT를 사용한다고 한다.

     

     

    Json Web Token(JWT)

    JWT의 공식 사이트 jwt.io에서는 다음과 같이 jwt를 설명하고 있다.

    더보기

    JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.

     

    Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.

    해석을 해도 되지만 Jwt에 대한 정보가 아무것도 없는 상태에서는 읽어도 이해가 잘 되지 않는다. 

    우선 Jwt는 Json 객체로 쓰여있는 정보를 암호화하여 토큰으로 전달하기 위해 사용된다 라고만 알고 넘어가자.

     

    정보를 암호화해야하는 이유는 너무나도 많지만, 제일 중요한 이유로 꼽을 수 있는 것은 당연히 정보 보호이다. 특히 사용자의 정보를 보호하여 유출되는 것을 막아야 한다.

     

    즉 Jwt를 가장 많이 사용하는 기능이 바로 사용자 인증이며, 정보 교류에 이용되기도 한다.

     

    JWT의 구조

    JWT는 Header, Payload, Signature의 3 부분으로 이루어지며, JSON 형태인 각 부분은 Base64로 인코딩 되어 표현된다. 또한 각각의 부분을 이어 주기 위해 . 구분자를 사용하여 구분한다.

     

    1. Header

    Header의 기본적인 구조는 다음과 같다. 

    { 
     "typ": "JWT",
     "alg": "HS256"
    }

    Header는 두 가지 정보를 가지고 있다.

    • typ: 토큰의 타입을 나타낸다. 여기선 당연히 JWT를 말한다.
    • alg: 토큰의 마지막 구분자인 Signature의 해싱 알고리즘을 나타낸다. JWT 공식사이트에서 소개한 글을 보면 HMAC, RSA, ECDSA 등을 사용한다고 나와있다.

    2. Payload

    Payload에는 토크에 담을 정보를 담고 있다. 여기에 담는 정보의 한조각들을 클레임(Claim)이라 부르고, 이는 Key-Value의 한 쌍으로 이뤄져있다.

     

    클레임은 다음과 같이 세가지로 나눌 수 있다.

    • Registerd Claim
    • Public Claim
    • Private Claim

    Register Claim

    등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보를 담기 위해 이미 정해진 클레임들이다. 등록된 클레임들은 모두 Optional하며 이미 등록된 클레임들의 이름들은 다음과 같다.

    • iss - 토큰 발급자(issuer)
    • sub - 토큰 제목(subject)
    • aud - 토큰 대상자(audience)
    • exp - 토큰 만료시간(expiration)
    • nbf - Numeric Date 형식으로 지정된 날짜가 지나기 전까지 토큰은 처리도지 않는다. (Not Before)
    • iat - 토큰이 발급된 시간(issue at)
    • jti - jwt의 고유 식별자 이를 이용해 중복 처리를 막는다.

    Public Claim

    공개 클레임들은 사용자가 정의하는 클레임으로 공개용 정보 전달을 위해 사용된다. 이는 충돌 방지를 위해 URI 충돌 방지 namespace가 포함된 포맷을 사용하거나 IANA JWT Registry에 정의되어 있어야 한다.

     

    Private Claim

    Register나 Public도 아닌 양 측간 협의하에 사용되는 클레임이다. 보통 서버 <-> 클라이언트 사이에서 사용된다. 

     

    Payload는 다음과 같이 작성될 수 있다.

    {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true
    }

     

    3. Signature

    Signature은 토큰을 인코딩 하거나 유효성을 검증하기 위해 사용되는 고유 암호화 코드다. Signature는 위에서 만든 Header와 Payload의 값을 각각 BASE64로 인코딩 하고, 인코딩한 값을 비밀키를 이용해 Header에서 정의한 알고리즘으로 해싱을 한다.

     

    만약 헤더에서 HS256을 해싱 알고리즘으로 정의한다면 Signature는 다음과 같이 나타낼 수 있다.

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

    이 값을 다시 BASE64로 인코딩하면 토큰에 넣을 수 있다.

     

     

    Jwt 공식 사이트에서는 Encode와 Decode를 할 수 있는 변환기를 제공하는데 다음과 같이 사용할 수 있다.

     

    위에서 언급했듯 안드로이드에서 Authentication 인증을 하기 위해서 Jwt를 사용한다. 웹에서는 Session 방식과 Jwt 방식 중에 골라 사용하는데, 안드로이드에서는 Session, Cookie를 사용하지 않기 때문에 Jwt를 이용해 인증을 진행하는 것이다. 

     

    다음 포스트에서 실제 JWT를 Spring 프로젝트에 적용시키고 작동하는 원리에 대해 설명할 것이다.

     

     

    Ref:

    - https://velog.io/@dnjscksdn98/JWT-JSON-Web-Token-%EC%86%8C%EA%B0%9C-%EB%B0%8F-%EA%B5%AC%EC%A1%B0

    - https://jwt.io/introduction 

    - https://velog.io/@mygomi/TIL-50-JWT%EC%97%90-%EB%8C%80%ED%95%B4-%EB%B0%9C%ED%91%9C%ED%95%B4%EB%B3%B4%EA%B2%A0%EC%8A%B5%EB%8B%88%EB%8B%A4

     

     

    '기술 면접 > Spring' 카테고리의 다른 글

    Stomp, SockJS를 이용하여 채팅 구현하기  (0) 2022.08.11
    Spring vs Spring boot  (0) 2022.08.09
Designed by Tistory.