JWT

susemeeee·2021년 12월 22일
0
post-thumbnail

JWT란?

JWT(Json Web Token)는 JSON을 사용해 가볍고 자가 수용적인 방식으로 정보를 안전성 있게 전달해 주는 토큰이다. 주로 회원 인증이나 정보 교류에 사용된다.

자가 수용적(self-contained) : 필요한 정보를 자체적으로 지니고 있다. 즉, JWT 토큰은 토큰에 대한 정보 유저 정보 등이 들어 있다. 또한, 토큰이 위조되지 않았다는 것을 증명할 signature를 포함하고 있다.


세션 기반 인증 VS 토큰 기반 인증

이전에는 주로 session을 이용한 인증 방식을 사용했다. 세션 기반 인증 방식은 서버 측에서 인증된 유저들의 정보를 메모리나 DB에 저장해 요청이 들어올 때 저장된 정보를 꺼내 사용한다.

하지만 이런 방식에는 소규모 시스템에서는 문제가 잘 보이지 않지만, 유저 수가 많아지면서 서버를 확장하기 시작하면 문제가 발생한다. 로그인 중인 사용자가 늘어나면서 서버의 메모리나 DB에 무리를 줄 수 있고, 서버를 확장하기 어려워진다.

이런 문제를 해결하기 위해 토큰 기반 인증을 사용하게 되었다. 토큰 기반 인증 방식은 인증된 사용자에게 토큰을 발급하고, 서버에 요청을 할 때 토큰을 함께 보내는 방식이다. 이 방식을 사용하면 인증된 사용자 정보를 서버에 저장하지 않아도 되기 때문에 서버 자원 절약이 가능하고, 서버 확장에도 유리하다.


JWT 구조

JWT 토큰은 기본적으로 header, payload, signature로 나누어져 있고, 세 부분을 .으로 연결해 놓은 형태이다.

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

header에는 토큰 자체에 대한 정보가 포함되어 있다.

  • alg : signature 해싱 알고리즘
  • typ : 토큰 타입(여기서는 JWT)

payload

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

payload에는 토큰에 담을 정보가 포함되어 있다. 여기에 담는 정보의 한 조각을 클레임(claim)이라고 하고, 이는 key/value 형태의 한 쌍으로 이루어져 있다. 클레임의 종류는 registered 클레임, public 클레임, private 클레임으로 나뉘어져 있다.

registered claim

registered claim은 토큰에 대한 정보를 저장하기 위해 이미 이름이 정해진 클레임이다. 클레임 사용은 모두 optional이다.

  • iss : 토큰 발급자
  • sub : 토큰 제목
  • aud : 토큰 대상자
  • exp : 토큰 만료 시간(NumericDate 형식이어야 한다. 예: 1516239022)
  • nbf : 토큰 활성 날짜(이 날짜 이전에는 토큰이 활성화 되지 않는다.)
  • iat : 토큰 발급 시간
  • jti : JWT 고유 식별자(중복 방지를 위해 사용)

public claim

public claim은 충돌 방지된 이름을 가지고 있어야 한다. 주로 URI 형태로 작성한다.

{
  "https://susemeeee.com/admin": false
}

private claim

private claim은 클라이언트 - 서버 간 협의하에 사용되는 클레임 이름이다. public claim과는 달리 이름이 중복 가능하다.

{
    "custom1": "qwerty"
    "custom2": 3
    "custom3": true
}

signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret
)

signature은 토큰을 인코딩하거나 유효성 검증 시 사용되는 고유한 암호화 코드이다. 앞서 만들어진 header, payload를 Base64 URL-safe 인코딩한 이후 header에 적힌 해시 함수를 적용해 서버 개인 키로 서명한다.


JWT 장단점

장점

  • 필요한 정보가 토큰에 포함되어 있기 때문에 인증 정보를 별도로 보관할 필요가 없다.
  • 쿠키를 사용하지 않기 때문에 쿠키를 사용함으로써 발생하는 취약점이 사라진다.
  • URL-safe 인코딩으로 URL 파라미터와 헤더로 사용이 가능하다.
  • 만료 시점을 설정해 자동으로 토큰 만료가 가능하다.

단점

  • 토큰에 담겨있는 정보는 암호화된 게 아닌, 단순 인코딩이기 때문에 민감한 정보를 담으면 유출될 수 있다.
  • 서버 측에서 임의로 토큰 삭제가 불가능하다.
  • 토큰에 포함하는 데이터가 많아질수록 토큰 길이가 길어진다.

0개의 댓글