JWT (JSON Web Token)

JS (TIL & Remind)·2022년 2월 28일
1

JWT (JSON Web Token) 이란?

JWT (JSON Web Token)의 공식 홈페이지에서 소개글을 번역하자면, JWT는 개방형 표준(RFC 7519)으로 두 당사자간에 정보를 JSON 형태로 안전하게 전송하기 위한 방법이라고 소개한다.

일반적으로 클라이언트와 서버, 서비스와 서비스 사이 통신 시 권한 인가(Authorization)를 위해 사용하는 토큰이다.

JWT의 장단점

장점

Stateless (무상태)

기존의 세션을 이용한 서버 기반 인증 방식의 경우 세션을 관리하기 위한 서버측 저장소에 대한 관리가 필요하지만, JWT는 서버에서 발급 후 검증만 하면 되기 때문에 서버측 저장소에 대한 관리가 필요 없다.

Scalability (확장성)

토큰 기반으로 하는 다른 인증 시스템에 접근할 수 있으므로 확장성이 좋다. 예를 들어, Google 로그인 등을 통한 어플리케이션 접근 등은 모두 토큰을 기반으로 인증하며, 선택적으로 이름이나 이메일 정보를 받을 수 있는 권한도 받을 수 있다.

Integrity (무결성)

JWT의 Secret key가 변경되면 Signature 영역이 변경된다. 이는 Token이 변조되었을 때 바로 알아차릴수 있음을 의미하므로 다시 말해, 콘텐츠가 변조되지 않았는지 확인할 수 있어 무결성을 보장한다.

단점

  • 모든 요청에 토큰이 전송되므로 토큰에 담기는 정보가 많을수록 네트워크 부하가 증가한다.
  • JWT는 매우 복잡한 표준이라 개발자가 잘못 이해하고 사용할 수 있다.

JWT 구조

JWT의 구조는 Header, Payload, Signature 문자열들이 각 점(.) 으로 구분되어있다.

JSON 객체를 문자열로 직렬화 하고, UTF-8과 Base64URLSafe로 인코딩하여 Header를 생성할 수 있다.

Header는 JWT를 어떻게 검증(Verify) 하는가에 대한 내용을 담고 있다.

alg는 서명 및 토큰 검증에 사용되는 알고리즘을 지정하고,

kid는 서명 시 사용하는 Public/Private Key를 식별하는 값이다.

Payload

Payload는 JWT의 내용이다. Payload에 있는 속성들을 클레임 셋(Claim Set)이라고 부르며, Claim Set은 토큰 생성자(클라이언트)의 정보, 생성 일시 등이나 클라이언트와 서버 간 주고 받기로 한 값들로 구성된다.

단, Payload는 암호화 되지 않으므로 암호화를 별도로 하거나 중요한 데이터를 담지 않아야 한다.

클레임 셋(Claim Set)

클레임 셋은 등록된 클레임(Registered Claim), 공개 클레임(Public Claim), 비공개 클레임(Private Claim)으로 구성되어 있다.

  • 등록된 클레임(Registered Claim) 등록된 클레임은 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들로, 모두 선택적으로 작성이 가능하며 사용하는 것을 권장한다.
    • iss (issuer) - 토큰 발급자
    • sub (subject) - 토큰 제목
    • aud (audience) - 토큰 대상자
    • exp (expiration) - 토큰 만료 시간
    • nbf (not before) - 토큰 활성 날짜
    • iat (issued at) - 토큰 발급 시간. 토큰 발급 이후의 경과 시간을 알 수 있음.
    • jti (JWT ID) - 토큰 식별자. 중복 방지를 위해 사용하며, 일회용 토큰에 사용.
  • 공개 클레임 (Public Claim) 사용자 정의 클레임으로, 공개용 정보를 위해 사용된다. 충돌 방지를 위해 URI 포맷을 이용한다.
  • 비공개 클레임 (Private Claim) 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.

Signature

Signature는 Header와 Payload를 합친 문자열을 서명한 값이다. Signature는 Header의 alg에 정의된 알고리즘과 서버가 지정한 비밀 키를 이용해 생성하고, Base64 URL-Safe로 인코딩 한다.

Header, Payload, Signature를 합쳐 완성된 JWT는 Header의 alg, kid 속성과 공개 키를 이용해 검증할 수 있고, 검증에 성공하면 JWT의 모든 내용을 신뢰할 수 있으며, Payload 값으로 접근 제어 등의 처리를 할 수 있다.

JWT를 이용한 인증 과정

  1. 클라이언트에서 서버로 로그인 인증을 요청한다.
  2. 서버에서 아이디, 비밀번호 확인 후 비밀 키를 이용해 Access Token(JWT)과 Refresh Token을 발급하여 클라이언트에게 보낸다.
  3. 클라이언트는 인증이 필요한 API를 요청할 때 Access Token을 Header에 담아서 보낸다.
  4. 서버는 Access Token의 Signature를 확인한 뒤 클라이언트에게 정보를 보낸다.
    1. Access Token이 만료되면 클라이언트는 Refresh Token으로 Access Token을 재발급 받는다.

Access Token (액세스 토큰)

리소스에 직접 접근할 수 있도록 해주는 정보만 가지고 있다.

Access Token이 탈취당하면 정보가 유출되므로 Refresh Token에 비해 짧은 만료기간을 가지고 있다.

Refresh Token (리프레시 토큰)

새로운 Access Token을 발급받기 위한 정보를 가지고 있다.

Access Token에 비해 긴 만료기간을 가지고 있다.

Access Token이 만료되면 Refresh Token을 이용하여 서버에서 새로운 Access Token을 발급 받는다.

profile
노션에 더욱 깔끔하게 정리되어있습니다. (하단 좌측의 홈 모양 아이콘)

0개의 댓글