스프링- JWT 구조+JWT 쓰는 이유

이진우·2023년 9월 10일
0

스프링 학습

목록 보기
11/41

JWT를 쓰는 이유?

결론부터 말하자면 RESTAPI에서는 주로 세션 기반의 방식보다 JWT 토큰을 사용한다.

RESTAPI는 서버가 클라이언트의 상태를 기억하지 않고 클라이언트에 독립적으로 작동하고 그로인해 업그레이드 등 변화가 쉬웠다. 세션 기반은 서버에서 클라이언트의 세션을 관리하였지만 JWT 토큰은 서버에 저장되지 않아서 RESTAPI의 stateless의 성격에 잘 맞는다.

또한 세션의 경우 그 정보가 특정 서버에 저장되기 때문에 로드 밸런스의 문제를 가져 여러가지 해결해야 할 경우도 있기 때문에 세션 기반의 방식보다 JWT 토큰 기반의 방식을 사용하는 이유 중 하나이다.

JWT란

먼저 생김새 부터 보면

위와 같이 생겼다.
JWT는 3가지 구성 요소(헤더+내용+서명)를 합쳐서 token을 생성한다.
차례차례 뜯어보면

header

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

헤더에는 이런 내용을 내포한다.
타입은 JWT타입이란 것을 나타내고 alg는 토큰을 검증할때 HS256이라는 알고리즘으로 할 것이다라는 것을 의미한다.
JSON 형태를 직렬화 한후 BASE64로 인코딩을 적용한 것이 위에서 aaaaaa를 의미한다.

payload

payload에는 실질적인 내용이 들어간다. 정보의 한 조각을 claim이라고 하는데 이 payload는 여러개의 claim으로 구성이 될 수 있다. 그 claim 은 미리 등록된 claim 과 사용자가 정의한 claim 으로 나눌 수 있다.

미리 정의된 claim의 예
iss: 토큰 발급자 (issuer)
sub: 토큰 제목 (subject)
aud: 토큰 대상자 (audience)
exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야합니다.
nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념입니다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않습니다.
iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있습니다.
jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.

등록된 claim 이라 해서 위의 모든 부분을 사용할 필요는 없으며 필요한 부분만 사용하면 된다.

사용자가 정의한 claim의 예
{
 "roles": ["user", "admin"]
 }

이렇게 권한 등 추가적인 내용을 집어 넣을 수도 있다.

Header와 마찬가지로 JSON 형태를 직렬화한후 BASE64 인코딩을 적용하였다. 그 내용은 위 그림에서 bbbbbb에 들어간다.

signature

시그니쳐 부분은
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

로 헤더를 base64로 인코딩한 것+payload를 base64로 인코딩한 것 을 아까 header에서 명시한 해시함수를 적용,그것을 개인 key로 서명한 것, 그것을 다시 base64로 인코딩한 것을 의미한다.

토큰을 보면 claim이나 내용적인 부분은 쉽게 파악이 가능하다.

https://jwt.io/ 의 사이트를 방문하고 토큰을 집어넣으면
쉽게 어떤 내용이 들어있는지 파악이 가능하다

이렇게 말이다.

하지만 이 내용을 위조하여 성공적으로 사용자가 그 토큰을 사용하는 것은 힘들다.

내용이 위조되었다 치자. 그러면 그 값으로 인해 시그니쳐 부분이 바뀌고 그러면 토큰을 받는 입장에서는 아 secret 값으로 안열리는 것을 보니 무언가 문제가 있다고 파악이 용이할 것이다.

참고할 만한 링크

https://www.youtube.com/watch?v=XXseiON9CV0

profile
기록을 통해 실력을 쌓아가자

0개의 댓글