JWT

가수왕·2022년 12월 13일

0. 개요

3번의 프로젝트에서 Springboot로 개발을 했지만 사용자 인증 관련 기능을 마지막 프로젝트에서 처음 해봤다. 인증에 jwt라는 것을 사용한다는 것은 알았지만 jwt가 무엇인지 왜 쓰는지 어떻게 쓰는건지 몰랐다. 그 때 알아봤던 걸 정리 해보려고 한다.

1. JWT

JWT 즉 Json Web Token이다. 인터넷 표준 인증 방식으로 인증에 필요한 정보들을 담아 서명해 사용한다.
사용자 인증에는 세션과 쿠키를 사용하는 방법도 있다.쿠키는 ID, PW를 그대로 담아 요청하고, 이를 바탕으로 인증하는 방식이다. 쿠키는 ID, PW등 민감정보가 노출되고, 조작당할 가능성등의 문제가 있다. 이를 방지하기 위해 세션을 이용한다. ID, PW등 민감정보를 담는게 아니라 "이 사용자는 믿을만한 사람이다" 라는 세션ID를 만들어 반환하고, 저장소에 저장해 요청 마다 세션ID를 비교해 인증하는 방식이다. 하지만 이렇게 저장소에 상태를 저장하기 때문에 http의 stateless를 위반한다. 이를 보완하기 위해 나온것이 JWT이다.

2. 구조

JWT는 Header, Payload, Signature 3개로 구성되어 있고 이 3개는 .으로 구분되어 있다. Header와 Payload는 Base64Url로 인코딩된다.

  • Header
    Header에는 토큰의 타입, 서명 생성시 사용된 알고리즘이 저장된다.

  • Payload
    Payload에는 사용자, 토큰에 대한 속성을 key-value형태로 저장한다. 이를 보통 Claim이라고 한다.

    Claim은 개발자 마음대로 넣을 수도 있다.(Public Claims, Private Claims)
    필수는 아니지만 미리 정의된 Claim도 있다 이를 Registered Claims라고 부른다.
    Registered Claim이름은 JWT의 컴팩트함을 살리기 위해 3글자로 이루어져 있다. (iss,exp,sub...) 아래 링크에서 미리 정의된 Claim들을 살펴볼 수 있다.

    https://www.rfc-editor.org/rfc/rfc7519#section-4.1

  • Signature
    서명은 중간에 메시지가 변경되지 않았는지 확인하기 위해 사용된다. 서명은 Header, Payload의 인코딩 된 값과 서버의 private key를 이용해 생성된다.

3. 단점

JWT토큰이 장점만 있는것은 아니다.

  • base64Url로 인코딩하기 때문에 정보 전달량이 상대적으로 많다.
  • payload는 암호화 되지 않아 민감정보를 저장하지 못한다.
  • 토큰이 탈취 당하면 만료까지 대처를 할 수 없다.

3번째 단점이 가장 치명적인 단점이다. 물론 이를 보완할 수 있는 방법이 있다. 토큰의 유효기간을 짧게(여기서 짧다는 1시간, 30분정도) 설정하면 된다. 하지만 유효기간이 짧으면 사용자가 서비스이용중에 토큰이 만료되어 새로 ID,PW를 입력해 로그인해야하는 일이 발생한다. 이를 방지하기 위한 대책도 존재한다.

4. Sliding Session

토큰의 유효시간이 짧으면 사용자가 계속해서 로그인해야하는 상황이 발생한다. 하지만 사용자가 특정행동(글 작성, 결제 등)을 하고 있는데 토큰이 만료되어 다시 로그인 해야한다면 사용자는 굉장한 불편함을 느낄거고, 우리 서비스를 다시 사용하고 싶지 않을 확률이 크다. 불편하니까
이를 막기위한 방법으로 사용자가 특정 행동을 하면 토큰의 만료시간을 연장한 토큰을 재발급해주는 방법이다.

5. Refresh Token

이제 앞에서 말했던 토큰은 Access Token이라고 하겠다. Refresh Token
이 방식은 AccessToken을 발급할 때 RefreshToken을 같이 발급하고 AccessToken이 만료되면 사용자가 다시 로그인하는 것이 아닌 RefreshToken을 활용해 다시 AccessToken을 발급하는 방식이다.

대략적인 흐름은 다음과 같다.

RefreshToken도 탈취당할 위험성이 존재한다.
이에대한 피해를 최소화 하기 위해 RTR(Refresh Token Rotation)이라는 방법을 사용하기도 한다. RTR은 쉽게 설명하면 RefreshToken을 1번만 사용하는 것이다. AccessToken을 다시 발급할 때 기존 Refresh Token을 폐기하고 새로운 RefreshToken을 발급하는 것이다.
이렇게 하면 해커는 Refresh Token을 탈취해도 1번만 사용할 수 있다.

0개의 댓글