JWT

Paul Mo·2022년 11월 16일
0

드디어 빗썸 코드 캠프 3기를 수료해서 이제야 블로그를 쓸 시간이 생겼다. 빗썸 코드 캠프에 대해 글을 써도 되는지 모르겠지만 추후에 기회가 된다면 교육 과정을 기록해서 블록체인에 대해 한번 정리를 해야겠다. 코드 캠프를 진행하면서 더 바빴던 이유는 최근에 이직을 준비하게 되면서 포트폴리오도 정리하고 면접도 여러 군데 다니다 보니 엄청 바쁜 일상을 보냈다. 오늘은 면접 질문 중에 공통적으로 여러 군데에서 질문을 받기도 하고 내가 잘 몰라서 제대로 답하지 못한 JWT에 관해 배워볼까 한다.

JWT란?

Json Web Token의 약자로 JSON 객체로 정보를 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 open standard (RFC 7519)라고 한다. 간단하게 말해 HTTPS를 사용하지 않고 안전하게 정보 전달을 하거나 회원 인증을 하는 데 사용하는 Web Token이다. JWT가 안전한 이유는 비밀키 or 공개/비 공개키를 사용하여 디지털 서명을 해서 데이터를 주고받기 때문이다.

JWT의 구조

JWT는 Header, Payload, Signature 로 나누어져 있고 세 개의 파트가 (.)으로 구분되어 있다. 예를 들면 이런 형태를 하고 있다.

xxxxx.yyyyy.zzzzz

  1. Header는 토큰의 타입과 사용 중인 해시 암호화 알고리즘으로 구성되어 있다.

    {
      "typ": "JWT",
      "alg": "HS256"
    }
  2. Payload는 토큰의 클레임이라는 데이터를 담고 있는데 보통 사용자에 대한 데이터를 가지고 있다. 종류는 Registered claims, Public claims, Priviate claims가 있다

    {
      "sub": "1234567890",
      "name": "John Doe",
      "admin": true
    }
  3. Signature는 인코딩 된 헤더와 페이로드, 비밀키, 그리고 헤더에 지정된 해시 알고리즘을 가져와서 서명을 하면 Signature가 만들어진다. HMACSHA256 해시 알고리즘을 사용했다고 가정을 하면 다음과 같은 Signature를 생성한다.

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

이렇게 완성된 JWT는 다음과 같은 형태를 가진다.

JWT 사용법

JWT를 만들어 봤으니 이제 사용하는 방법을 알아보자. 보통 클라이언트가 회원가입이나 로그인을 하면 서버가 JWT 토큰을 생성해서 클라이언트에게 넘기고 그 클라이언트는 서버에게 데이터를 요청할 때마다 Authorization Header에 Bearer 스키마를 사용해서 데이터 통신을 하게 된다.

Authorization: Bearer <token>

HTTP 헤더를 통해서 JWT 토큰을 보낼 때 주의할 점이 있는데 토큰의 크기가 너무 크지 않아야 한다. 일부 서버는 8KB 이상을 허용하지 않기 때문에 너무 많은 정보를 토큰에 넣지 말고 간결하고 정말 필요한 정보만 넣어서 사용하는 것을 권장한다.

JWT 심화

JWT에는 사실 두 가지 종류가 있다. Access Token과 Refresh Token이 있는데, 액세스 토큰은 서버 측 리소스에 접근할 때 본인 인증 토큰으로 사용되고 리프레쉬 토큰은 액세스 토큰을 생성하는 용도로 사용된다. 도대체 왜 이런 방식으로 사용되는지 알아보자.

Access Token는 짧은 유효 기간을 설정해 액세스 토큰이 탈취당한다고 해도 유효기간이 지나면 사용할 수 없게 한다. 정상적인 클라이언트는 유효기간이 지난 액세스 토큰을 리프레쉬 토큰으로 새로 생성해서 사용하면 된다.

Refresh Token은 긴 유효 기간을 설정해 액세스 토큰이 만료돼도 서버에 리프레쉬 토큰을 전송해서 클라이언트가 다시 로그인을 하거나 본인 인증을 다시 하는 일 없이 데이터 통신을 지속 가능하게 한다. 만약 해커로부터 리프레쉬 토큰을 탈취당할 경우 해커가 새로운 액세스 토큰을 생성해 서버에 접근한다고 해도 유효 기간이 지나지 않았음에도 액세스 토큰을 새로 생성해서 보내거나 유효 기간이 지났어도 정상적인 클라이언트가 액세스 토큰을 새로 생성해서 보내게 되면 충돌이 일어나기 때문에 서버는 모든 토큰을 만료 처리를 해서 로그인이나 본인 인증을 다시 요구한다.

결론

사실 이 질문을 받은 두 면접에서 탈락의 고배를 마시게 되었는데 이 질문 때문이었는지는 모르겠으나 어렴풋이 알고 있는 것과 이렇게 구조, 사용법, 종류까지 모두 알고 설명을 하는 것은 천지 차이라는 것을 느끼었다. 괜히 모르는 것을 아는 척하면 더 눈에 돋보이는 것 같다... 현재 앱에서도 Cognito를 사용해서 JWT를 생성해 모바일 앱에서 통신을 하는 데 사용하는데 실제로 내가 사용하면서도 이게 무엇인지 잘 모르고 사용했던 내가 참 바보 같았다. 앞으로도 면접 때문이 아니라 더 나은 개발을 위해 무엇을, 왜, 어떻게 사용하는지 이해하고 개발을 하도록 하자. JWT는 이제 확실히 알게 되었으니 다음에 질문을 받게 된다면 꼭! 잘 설명하고 합격을 하겠다!!!

출처:

profile
프론트 엔드 개발자

0개의 댓글