JWT(JSON Web Token)

코난·2024년 4월 8일
0

CS 면접 정리

목록 보기
48/67

JWT란?

JWT는 JSON Web Token의 약자로 사용자를 인증하고 식별하기 위한 토큰 기반 인증이다. 토큰 자체에 사용자의 권한 정보나 서비스를 사용하기 위해 정보가 포함된다. RESTful과 같은 무상태 환경에서도 사용자 데이터를 주고받을 수 있게 된다. 시션을 사용하게 될 경우 쿠키 등을 통해 사용자를 식별하고 서버에 세션을 저장했지만, 토큰을 클라이언트에 저장하고 요청시 HTTP 헤더에 토큰을 첨부하는 것만으로도 단순하게 데이터를 요청하고 응답받을 수 있다.

보통 Authorization HTTP 헤더를 Bearer + 토큰의 형태로 설정하여 클라이언트에서 서버로 전송되며, 서버에서는 토큰에 포함되어 있는 서명 정보를 통해 위변조 여부를 빠르게 검증할 수 있게 된다. Base64로 인코딩되어 있어 육안으로 보면 eyJ로 시작하는 아주 긴 문자열이지만 실제로 저장되어 있는 내용은 JSON 형식의 토큰이다. 같은 문자열에 대해 항상 같은 인코딩 문자열을 반환한다.

JWT의 구조


하나의 JWT 토큰은 헤더(Header)와 페이로드(Payload), 서명(Signature) 이렇게 세 부분으로 이루어지며 각 구역이 . 기호로 구분된다.

세 번째 부분인 서명에는 헤더와 페이로드가 비밀키로 서명되어 저장된다.

헤더 (Header)

첫 번째 부분인 헤더에는 토큰의 유형과 서명 알고리즘이 명시된다. typ와 alg 두 가지 정보로 구성된다.

  • typ : 토큰의 타입을 지정 ex) JWT
  • alg : Signature를 해싱하기 위한 알고리즘을 지정 ex) HS256

페이로드 (Payload)

두 번째 부분인 페이로드에는 소위 claim이라고 불리는 사용자의 인증/인가 정보가 담긴다. 클레임은 총 3가지(등록된 클레임, 공개 클레임, 비공개 클레임)로 나누어지며, Json(Key, Value) 형태로 다수의 정보를 넣을 수 있다.

  • 등록된 클레임
    등록된 클레임은 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들이다. JWT를 간결하게 하기 위해 key는 모두 길이 3의 String이다.

    • iss : 토큰 발급자(issuer)
    • sub : 토큰 제목(subject), 주로 unique한 값 사용
    • aud : 토큰 대상자(audience)
    • exp : 토큰 만료 시간(expiration)
    • nbf : 토큰 활성 날짜(not before)
    • iat : 토큰 발급 시간(issued at)
    • jti : jwt 토큰 식별자(jwt id)
  • 공개 클레임
    공개 클레임은 사용자 정의 클레임으로 공개용 정보를 위해 사용된다. 충돌 방지를 위해 URI 포맷을 이용한다. ex) "xxx@xxx.com" : true

  • 비공개 클레임
    비공개 클레임은 사용자 정의 클레임으로 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다. ex) "token_type" : access

서명 (Signature)

서명은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다. 서명은 위에서 만든 헤더와 페이로드의 값을 각각 BASE64로 인코딩하고, 인코딩한 값을 비밀키를 이용해 헤더에서 정의한 알고리즘으로 해싱하고, 이 값을 다시 BASE64로 인코딩하여 생성한다.

토큰 기반 VS 세션 기반


JWT의 장점

  • 로컬에 저장하기 때문에 서버 용량에 영향을 끼치거나 받지 않는다.
  • 키를 통해 서명되기 때문에 보다 안전하다.
  • 네트워크 부하가 적다.
  • 재사용성이 높다.

Stateful해야 하는 세션의 단점을 보완하기 위해 만들어진 JWT는 별도의 세션 저장소를 강제하지 않기 때문에 Stateless하여 확장성이 뛰어나고 Signature를 통한 보안성까지 갖추고 있다.

JWT의 단점

  • 토큰의 크기가 커질수록 트래픽에 영향을 미칠 수 있다.
  • 토큰은 발급되면 만료 기간 변경이 불가능하므로 토큰 만료 처리를 구현해야 한다.
  • Payload는 암호화 되어있지 않기 때문에 민감 정보를 저장할 수 없다.
  • 토큰이 탈취당하면 만료될 때까지 대처가 불가능하다.

특히, 마지막 단점은 치명적인데 서버에서 클라이언트의 상태를 저장하지 않는 Stateless한 상황이므로 탈취를 확인해도 방법이 없다. 이럴때를 위해 EXP, Expiration Time(만료시간)을 짧게 가져가면 된다.
그렇게 한다면, 토큰이 탈취되었을 때 서버가 이를 강제로 끊지는 못하지만 짧은 시간만 유효하기에 최소한의 보안성을 보장할 수 있다. 하지만 로그인이 계속 끊겨 사용자의 입장에서는 불편함이 생길 수 있다.

짧은 JWT 유효시간을 보완하는 방법

  1. Sliding Session
    Sliding Session을 사용하면 유저가 특정 action을 취했을 때, 새롭게 만료시간을 늘린 JWT를 다시 제공함으로써 만료시간을 연장하여 보완하는 방법이다. 다만, 접속이 단발성으로 일어난다면 Sliding Session으로 연장시켜줄 수 없는 상황이 생기고, 너무 긴 Access Token을 발급시켜준 상황이라면 Sliding Session 때문에 무한정 사용하는 상황이 발생할 수 있다.

  2. Refresh Token
    가장 많이 사용하는 방법으로 JWT를 처음 발급할 때 Access Token과 함께 Refresh Token이라는 토큰을 발급하여 짧은 만료시간을 해결하는 방법이다. 짧은 시간이 아닌 비교적 긴 시간의 만료시간을 가진 Refresh Token은 말 그대로 Access Token을 Refresh 해주는 것을 보장하는 토큰이다. 만약 클라이언트가 Access Token이 만료됨을 본인이 인지하거나, 서버로부터 만료됨을 확인받았다면 Refresh Token으로 서버에게 새로운 Access TOken을 발급하도록 요청하여 발급하는 방식이다.


참고

https://velog.io/@chuu1019/%EC%95%8C%EA%B3%A0-%EC%93%B0%EC%9E%90-JWTJson-Web-Token
https://blog.bizspring.co.kr/%ED%85%8C%ED%81%AC/jwt-json-web-token-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9/
https://mangkyu.tistory.com/56
https://brunch.co.kr/@jinyoungchoi95/1
https://puleugo.tistory.com/138

profile
몸은 커졌어도, 머리는 그대로... 하지만 불가능을 모르는 명탐정 현아! 진실은 언제나 하나!

0개의 댓글