헷갈리는 것들 공부

JWT(Json Web Token) 그게 대체 뭔데?

예나부기 2021. 11. 16.

요새 신입 개발자 포트폴리오에 필수적으로 포함되어야 한다는 (뇌피셜) JWT를 다뤄보자.

처음엔 JWT 발급 + 유효성 검사를 이해 하는데 보름이 걸렸다. 

JWT에 찾아보면 많은 정보가 나오지만, 그래서 어떻게 하라는거지? 가 궁금한 사람들을 위해 쓴다.

 

JWT (Json Web Token) 

-개방형 표준(RFC7519)

-서버와 클라이언트 간 정보를 주고받을 때 HTTP 리퀘스트 헤더에 JSON 토큰을 넣은 후 이를 통해 인증

-한마디로, JSON 형식의 토큰을 이용해서 상호 보안을 지킬 수 있게 하는 것이다!

 

왜 쓰는가?

-두 개체 간 정보를 주고받을 때 안전하게 주고 받기 위해서! 

 

특징

-Self-Contained : 토큰 자체를 정보로 사용한다.

-크기가 작아서 URL파라미터나 HTTP header에 담아서 빠르게 전송한다.

-Payload에 유저에 대한 정보를 담을 수 있다. 이 장점은 뒤에 설명

 

구조

-3가지 구조로 이루어져있고, 각 구조는 '.'으로 구분되어 있다. 각 부분은 Base64로 인코딩 되어서 표현된다.

-아래 그림 중 왼쪽 Encoded에 세 가지 색상이 보이고, '.'으로 연결되어 있는 것이 보일것이다.

-이제 오른쪽을 보면, 각 색상이 어떤 부분인지 구분되어있다.

맨 앞은 Header , 그 다음은 Payload, 마지막은 Signature라는 뜻이다.

-각 부분마다 담을 수 있는 정보가 다른데, 이 세 가지 정보가 합쳐져 JWT가 되는 것이다! 

-참고로 위의 사이트는 JWT 공식 사이트이다. 위와 같은 Debugger가 필요하다면 들어가보자. https://jwt.io/

 

각 구조에 대하여 알아보자. 이 구조를 알아야 각 부분에 정보를 담아 토큰을 만들 수 있다.

1)헤더(Header)

-헤더를 만드려면 typ과 alg를 담아준다.

 

  • typ: 토큰의 타입을 지정한다. 우리는 JWT를 이용할 거니까 JWT라고 써준다.
  • alg: Signature를 해싱하기 위한 알고리즘을 지정하는 부분, 서명(Signature) 및 토큰 검증에 사용 ex) HS256(SHA256) 또는 RSA

 

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

2)페이로드(Payload)

-페이로드는 Claim이란 것을 담고 있는 부분이다.

-Claim 정보를 담는 조각이라고 보면 되고, 3가지 타입이 있다. (등록된 클레임, 공개 클레임, 비공개 클레임)

그 중 , # 등록된 클레임

-미리 정의되어 있는 클레임이다. 여기에 있는 것을 다 쓸 필요는 없고, 필요한 것만 골라서 넣어준다.

 

  • iss: 토큰 발급자(issuer)
  • sub: 토큰 제목(subject)
  • aud: 토큰 대상자(audience)
  • exp: 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370
  • nbf: 토큰 활성 날짜(not before), 이 날이 지나기 전의 토큰은 활성화되지 않음
  • iat: 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간을 알 수 있음
  • jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용

-여기서는 등록된 클레임만 이용해보도록 한다. 나머지는 다른 티스토리에 자세히 나와있다.

 

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

3)Signature

-위에서 만든 헤더와 페이로드의 값을 각각 Base64로 인코딩 하고, 인코딩한 값을 비밀키를 이용해 

헤더에서 정의한 알고리즘 (위 코드블록에서 HS256으로 지정했었다)으로 해싱한다.

그 후 이 값을 다시 Base64로 인코딩해서 만들어진다.

-복잡하지만, 인코딩 된 헤더와 페이로드 + 비밀키 + 헤더에서 지정한 alg로 생성된다는 뜻이다.

 

이번 프로젝트에서는 JSON으로 통신하는 API를 만들면서 JWT를 이용했는데,

내가 이해 한 과정은 이와 같다.

 

1) API 요청하는 쪽에서 API 페이지로 Request를 한다.

2) API페이지에서 그 요청의 Header부분에 Authorization이 있는지 확인한다.

3-1) Authorization이 없다면 JWT가 없이 API를 call 했다는 뜻이다. 그러니 발급해준다. 

이 때 발급하는 토큰은 만료 기간이 정해져 있어서, 지정한 시간 동안만 유효하다.

만료 기간이 정해진 token의 특성 상, refresh token이라는 것도 함께 발급해서 사용을 용이하게 하는데

이에 대한건 나중에 다뤄보자. 나의 경우 여기서는 그냥 refresh token 없이 발급했다.

+이 때 발급 받은 토큰을, 사용자는 안전한 곳에 보관해 놨다가 API 요청을 할 때 같이 보내는 것이다!

3-2) Authorization이 있다면 Header에 담겨져 온 토큰을 추출해서 유효성 검사를 한다.

이 유효성 검사에는 만료 기간이 지나진 않았는지, 유효한 토큰 형식인지, 토큰 정보가 유효한지 등을 검사한다.

4) 토큰 유효성 검사를 했는데 유효하다고 판단되면, 그 때 사용자가 원하는 API Response를 JSON으로 해주는거다.

 

자세한 구현은, 다음 포스팅으로 넘겨보자!

<다음 편에 계속>

댓글