[Authorization] 2. JWT Token을 이용한 인증

등장 계기

기존에는 쿠키-세션 방식을 통해 사용자 인증을 수행하였다. 이 방법은 서버가 사용자를 식별하기 위해 사용자의 정보를 서버에 저장하고 있어야 했고, 이는 다음의 문제를 발생시켰다.

  1. 모든 사용자의 정보를 저장해야 하기 때문에 서버에 부하를 일으킨다.
  2. 서버를 확장하기 어려워진다. 서버가 여러 대가 되면 세션 정보를 공유해야 하는데, 이 과정이 복잡하기 때문

따라서 Stateful 방식으로 사용자 정보를 관리하는 것에 어려움을 느끼게 되었고, 이에 대한 대안으로 등장한 Stateless 방식의 인증 기법이 바로 Token을 이용한 인증 기법이다.

JWT(JSON Web Token)

토큰 중에서도 JSON 형식의 데이터를 이용하는 토큰

JWT Format

JWT는 3개의 요소인 Header, Payload, Signature로 구성된다.

각 요소는 문자열로 인코딩되며, 디코딩하면 JSON 형태의 데이터를 얻을 수 있다.

  • Header
    • 헤더는 typ, alg로 구성된다.
    • typ: 토큰의 타입을 지정 (ex: JWT)
    • alg: 암호화 알고리즘을 지정 (ex: SHA256)
  • Payload
    • 페이로드는 해당 토큰을 통해 얻고자 하는 정보들로 구성된다.
    • 이는 클레임(Claim)이라고 부른다.
  • Signature
    • 토큰을 인코딩하거나 유효성을 검증할 때 사용하는 고유 암호화 코드
    • 다음과 같은 순서를 통해 생성된다.
      1. 헤더와 페이로드를 각각 BASE64로 인코딩
      2. 1번의 결과값을 비밀 키를 통해 헤더에서 정의한 알고리즘으로 해싱
      3. 2번의 결과값을 다시 BASE64로 인코딩

사용법

생성된 토큰은 문자열 형태를 가지며, 이는 클라이언트의 로컬 스토리지에 저장되어 서버에게 인증이 필요한 API를 요청할 때 전송되어야 한다.

이를 위해 토큰은 헤더에 실으며, 다음과 같은 형식으로 전송된다.

{
    "Authorization": "Bearer {token value}"
}

인증 흐름

  1. 사용자가 아이디/비밀번호를 통해 로그인을 시도
  2. 서버는 해당 정보가 맞다면 토큰을 발급
  3. 클라이언트(브라우저)는 토큰을 로컬 스토리지에 저장해 둔 뒤 서버에 요청을 보낼 때마다 해당 토큰을 헤더에 실어 보냄
  4. 서버는 토큰을 검증하고, 유효한 토큰이라면 요청에 응답
    • 주로 유효하지 않은 토큰이거나 토큰이 없다면 401 Unauthorized로 응답