JWT에 대해 알아보는 시간

juyeong-s·2023년 3월 18일
1

브라우저

목록 보기
2/2

부스트캠프 활동 중 한번 정리한 적이 있었는데, 요즘 공부를 안했더니 개념을 까먹어서 다시 정리해본다!

공식문서를 직접 해석하고 여러 블로그들을 참고해서 정리했습니다 😉

보통 서버가 클라이언트의 인증을 확인하는 방법으로 쿠키, 세션, 토큰 3가지가 있다. JWT는 토큰 인증 방식 중 하나다. JWT와 무엇인지, 어떻게 동작하는지, 왜 사용하는지 제대로 알아보자.

JWT

JWT는 JSON Web Token의 줄임말로 인증에 필요한 정보들을 암호화시킨 JSON 토큰이다. JWT 기반 인증은 JWT 토큰(Access Token)을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다.

JWT의 구조

JWT는 .을 구분자로 나누어지는 세가지 문자열의 조합으로 구성되어 있다.
Header.Payload.Signature

JWT에서 사용할 타입과 해시 알고리즘 종류가 담겨있다. 일반적으로 토큰 유형(typ)서명 알고리즘(alg) 두 부분으로 구성된다.

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

위 코드를 Base64Url로 인코딩하여 JWT의 첫번째 부분인 Header를 형성하게 된다.

Payload

서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있다. 즉, 서버와 클라이언트가 주고받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있는 섹션이다.

{
  "id": 123456789,
  "name": "JuYeong-s",
  "age": 24
}

페이로드는 대표적으로 Registered claims, Public claims, Private claims 이렇게 세 가지 데이터 타입으로 나뉜다.

Registered claims: 미리 정의된 클레임

  • iss(issuer): 발행자
  • sub(subject): 토큰 제목
  • aud(audience): 토큰 대상 - 수신인을 식별함
  • exp(expireation time): 토큰 만료 시간
  • nbf(not before): JWT가 토큰이 처리되지 않아야 할 시점 - 이 시점이 지나기 전까지는 토큰이 처리되지 않는다.
  • iat(issued At): 발행한 시간
  • jti(JWI ID): 토큰 고유 식별자

Public claims: 공개 클레임

  • JWT를 사용하는 사용자가 마음대로 정의할 수 있는 클레임이다. 그러나 충돌을 방지하기 위해 IANA JSON Web Token Registry에 따라 정의하거나 충돌 방지 네임스페이스를 포함하는 URI 형식으로 정의하는 것이 좋다.

Private claims: 비공개 클레임

  • 통신을 주고받는 당사자들끼리 협의하여 자유롭게 키/값을 정의할 수 있는 클레임

Signature

Header, Payload를 Base64 URL-safe Encode를 한 이후 Header에 명시된 해시함수를 적용하고, 개인 키(Private Key)로 서명한 전자서명이 담겨있다.

Signature를 생성하기 위해서는 인코딩된 Header, 인코딩된 Payload, 비밀 키, Header에 명시된 알고리즘이 필요하다.

HMACSHA356(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret key
)

시그니처는 (헤더 + 페이로드)와 서버가 갖고 있는 secret key 값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화를 한다.

Header와 Payload는 단순히 인코딩된 값이기 때문에 제 3자가 복호화나 조작을 할 수 있지만, Signature는 서버의 secret key가 유출되지 않는 이상 복호화할 수 없다.
따라서, Signature는 토큰의 위조 여부를 판단하는데 사용된다.


JWT는 어떻게 작동할까?

사용자가 성공적으로 로그인하면 JWT가 반환된다. 사용자가 로그인이 필요한 경로나 리소스에 엑세스하려고 할 때마다 Baerer 스키마를 사용하여 Authorization 헤더에 JWT를 실어 보내야 한다.

Authorization: Bearer <token>

이때 HTTP 헤더를 통해 JWT 토큰을 보낼 경우 토큰이 너무 커지지 않도록 해야 한다. 또한, 보안 문제때문에 민감한 세션 데이터를 브라우저 저장소에 저장하지 않도록 해야 한다.

브라우저 저장소에 저장하지 않을 경우, 헤더의 Authorization에 토큰을 실어보내면 쿠키를 사용하지 않기 때문에 CORS는 문제가 되지 않는다.

(저장하지 않고 JWT을 실어보내는 방법으로는 클라이언트 상태를 사용하는 방법이 있음.)

API 또는 리소스에 엑세스하기 위해 JWT를 얻고 사용하는 흐름

  1. 애플리케이션 또는 클라이언트가 권한 부여 서버에게 권한 부여를 요청한다.
  2. 권한이 부여되면 권한 서버는 애플맅케이션에 엑세스 토큰을 반환한다.
  3. 애플리케이션은 엑세스 토큰을 사용하여 보호된 리소스에 엑세스한다.

왜 JWT를 사용해야 할까?

SWT(Simple Web Tokens)SAML(Security Assertion Markup Language Tokens) 과 비교할 때 JWT의 이점에 대해 알아보자.

  • JSON은 XML보다 단순하기 때문에 인코딩될 때 크기도 더 작기 때문에 XML 기반의 SAML 방식보다 크기가 작다. 따라서, HTML 및 HTTP 환경에서 전달하기에 좋은 선택이다.

  • 보안 측면에서, SWT 방식은 대칭 키 방식인 HMAC 알고리즘을 사용하는 비밀 키에 의해서만 서명되지만, JWT와 SAML 토큰은 공개키/개인키 쌍 방식을 쓸 수 있다.
    인증 과정에서 대칭 키 방식은 속도는 빠르지만 키를 교환해야 한다는 문제와 키 배송 문제가 있다.

  • JSON 파서는 객체 형식이기 때문에 대부분 프로그래밍 언어에 일반적이다. 반면, XML은 객체에 바로 매핑되기 어렵기 때문에 SAML보다 JWT가 더 사용하기 쉽다.
    - JSON과 XML

참고

profile
frontend developer

0개의 댓글