Programming/JAVA

JWT 란?

8ugust 2022. 1. 21. 00:32

 

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

 위와 같이 문자열이 .(dot) 에 으해 세 등분으로 구분되어 있는 형태를 최소 한 번 이라도 본 적이 있다면 당신은 JWT가 구현된 서버를 이용해본 적이 있거나, 혹은 JWT를 직접 구현해본 개발자일 것이다. JWT란 JSON Web Token의 줄임말로, 클라이언트와 서버 or 서비스와 서비스 사이에서 권한을 부여하고 확인하기 위해 사용하는 토큰이다. 위 문자열을 jwt.io 사이트를 통해 해석을 해보면

 

 

 

 이렇게 .(dot) 에 의해 구분된 세 단락이 우측의 Decoded 란에 HEADER / PAYLOAD / SIGNATURE 영역으로 나누어지는 것을 확인 할 수 있다. JWT는 이렇게 세 영역으로 구성되어 있으며, 각 영역마다 포함하고 있는 데이터의 의미가 상이하기 때문에 이해하고 넘어가야한다.

 

 

 


 

1  )  HEADER (헤더)

JWT는 기본적으로 base64로 인코딩된 문자열 형태를 띄고있다. JWT를 전달받은 서버의 입장에서 생각해보면 이게 JWT인지 아니면 정말 무의미한 문자열인지 알 방법이 없다. 따라서 HEADER에는 해당 문자열이 JWT이며, 이를 해독하기 위해 어떤 알고리즘을 사용해야 하는지 알려주는 내용이 담긴다.

 

 

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

 alg : 사용된 해싱 알고리즘. 주로 SHA256 or RSA 사용.

 typ : 토큰 타입. JWT 토큰이기 때문에 JWT 고정.

 

 

 

2  )  PAYLOAD (페이로드)

 JWT의 여러가지 정보를 담고 있는 영역이다. 정보 하나하나를 클레임(Claim) 이라고 부르며, key : value 형태로 구성되어있다. 클레임은 기본적으로 옵션 형태를 띄고 있기에 원하는 정보를 아무렇게나 입력해서 사용할 수 있지만, 기본적으로 등록된 클레임(Registrered Claims)들은 다른 내용으로 사용할 수 없다. 등록된 클레임의 종류는 다음과 같다.

 

 

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}
  • iss : 토큰 발급자 (Issuer)
  • sub : 토큰 제목 (Subject)
  • aud : 토큰 수신자 (Audience)
  • exp : 토큰 기한 (Expiration Time)
  • nbf : 토큰 활성시간 (Not BeFore. 해당 시간 이전엔 토큰 비활성.)
  • iat : 토큰 발급시간 (Issued At)
  • jti : 토큰 식별자 (JWT Identifier)

 위 예제에서 sub & iat는 등록된 클레임(Registered Claims)이며, name은 사용자 정의 클레임이다. 등록된 클레임의 사용 또한 옵션이므로 nbf 처럼 특정 활성시간이 필요하지 않다면 제외시킬 수 있다.

 

 

 

3  )  SIGNATURE (서명)

 JWT는 위에서 언급했듯 기본적으로 base64로 인코딩된 문자열이다. 즉 문자열만 있다면 누구나 이 JWT에 무슨 내용이 삽입되어 있는지 확인할 수 있는데 더해, 언제든 해당 내용을 임의로 변경할 수 있다. 즉 위변조가 가능하다는 뜻인데, 서버 입장에선 이 JWT가 위변조 되었는지 확인이 반드시 필요하다. 이를 위해 마지막 Signature 영역이 사용된다.

 

 

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  
your-256-bit-secret

)

 SIGNATURE의 내용은 HEADER에 언급된 해싱 알고리즘으로 HEADER의 내용과 PAYLOAD의 내용을 암호화한 뒤, 암호화된 문자열을 다시 Base64로 인코딩된 내용이 삽입되어있다. 즉 아무리 HEADER와 PAYLOAD의 내용을 변경하여 위변조된 JWT를 사용하려고 한들, SIGNAUTRE에 의해 위변조된 JWT라는 것이 들통난다는 것이다.

 

 

 


 이렇게 JWT가 무엇인지에 대해 간단히 알아보았다. 다음 시간에는 널리 공인된 JWT 패키지인 tymon/jwt-auth 패키지를 사용하여 Laravel에서 JWT를 구현하고 실제로 API를 구동하는 방법에 대해 기술해보겠다.