Published on

JWT (JSON Web Tokens)

Authors
  • avatar
    Name
    Hyo814
    Twitter

JSON Web Tokens (JWT)

기본 설명

JSON Web Token (JWT)은 웹 표준으로서, 두 시스템 사이에서 안전하게 정보를 JSON 객체 형태로 전송하기 위해 사용됩니다. JWT는 정보를 안전하게 전송할 수 있도록 디지털 서명이 되어 있으며, 일반적으로 HMAC 알고리즘을 사용하거나 RSA나 ECDSA와 같은 공개 키/개인 키 쌍을 이용하여 서명됩니다.

구조

JWT는 세 부분으로 구성됩니다: 헤더(Header), 페이로드(Payload), 서명(Signature).

  • 헤더: 토큰의 유형과 사용된 해시 알고리즘을 설명합니다.
  • 페이로드: 토큰에 담을 클레임(claim) 정보가 포함됩니다. 클레임은 사용자의 식별 정보나 토큰의 유효 기간 등이 될 수 있습니다.
  • 서명: 헤더와 페이로드를 해싱하고 비밀 키로 서명하여 생성된 부분입니다.

예시

JWT 예시:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

이 예시는 HMAC SHA256 알고리즘을 사용하여 서명된 토큰입니다.

활용 방법

  • 인증: 서버는 클라이언트가 로그인할 때 JWT를 생성하고 클라이언트는 이후 요청에서 이 JWT를 사용하여 자신을 인증할 수 있습니다.
  • 정보 교환: JWT는 두 당사자 사이에서 안전하게 정보를 교환하기 위해 사용할 수 있습니다. 정보가 JWT에 서명되어 있기 때문에 정보가 조작되었는지 확인할 수 있습니다.

Access 토큰 만료 시 request 처리 방법

Access 토큰이 만료되었을 때 이를 처리하는 방법에 대해 알아보겠습니다. 이 과정은 다음과 같은 단계로 이루어집니다:

  1. Access 토큰 만료 확인: 서버에서 응답 코드로 토큰 만료를 알립니다. 보통 HTTP status 401 (Unauthorized)을 사용합니다.
  2. Refresh 토큰으로 새 Access 토큰 요청: 만료된 Access 토큰을 갱신하기 위해 Refresh 토큰을 사용합니다. Refresh 토큰은 상대적으로 긴 유효기간을 가지며, 이를 사용해 새로운 Access 토큰을 발급받습니다.
  3. 새로운 Access 토큰으로 재요청: 새로운 Access 토큰을 받아 기존 요청을 재시도합니다.

1. Access 토큰 만료 확인

서버에서 HTTP status 401 (Unauthorized) 응답 코드를 반환하여 토큰이 만료되었음을 알립니다.

2. Refresh 토큰으로 새 Access 토큰 요청

Access 토큰이 만료되었을 때, Refresh 토큰을 사용하여 새로운 Access 토큰을 요청합니다. 다음은 이 요청의 예시 URL과 HTTP Body입니다:

  • URL: POST /auth/token
  • HTTP Body:
{
    "grant_type": "refresh_token",
    "refresh_token": "your_refresh_token_here"
}

3. 새로운 Access 토큰으로 재요청

새로운 Access 토큰을 받아 기존 요청을 재시도합니다.

토큰 권한 없음 에러 Response

토큰의 권한이 없을 때 서버는 403 Forbidden 응답을 반환합니다. 보통 응답 Body에는 에러 메시지가 포함됩니다.

예시 Response

  • HTTP Status Code: 403
  • HTTP Body:
{
    "error": "insufficient_scope",
    "error_description": "The token does not have the necessary permissions."
}

Refresh 토큰 프론트 저장 장소

Refresh 토큰은 보안상 중요한 정보이기 때문에 안전하게 저장해야 합니다. 가장 안전한 방법 중 하나는 HttpOnly 쿠키를 사용하는 것입니다.

쿠키에 저장하기 (HttpOnly)

HttpOnly 속성을 가진 쿠키는 JavaScript에서 접근할 수 없어 XSS 공격을 방지할 수 있습니다. 쿠키 설정 예시는 다음과 같습니다:

document.cookie = "refresh_token=your_refresh_token_here; HttpOnly; Secure; SameSite=Strict";

로그인 안한 상태에서 요청 할 때

401 Unauthorized: 로그인하지 않은 상태에서 인증이 필요한 리소스에 접근하려고 할 때 사용합니다.

예시 응답

{
    "status": 401,
    "error": "Unauthorized",
    "message": "Authentication required."
}

Refresh Token 만료 됐을 때

401 Unauthorized: Refresh token이 만료된 경우에는 사용자가 다시 인증을 해야 하므로 401 Unauthorized 상태 코드를 사용합니다.

예시 응답

{
    "status": 401,
    "error": "Unauthorized",
    "message": "Refresh token has expired."
}

Refresh Token이 DB에 저장된 것과 다를 때 (유효하지 않은 경우)

403 Forbidden: Refresh token이 유효하지 않거나 저장된 것과 다를 때는 접근이 금지되었음을 나타내기 위해 403 Forbidden 상태 코드를 사용합니다.

예시 응답

{
    "status": 403,
    "error": "Forbidden",
    "message": "Invalid refresh token."
}

따라서, 상태 코드는 다음과 같이 구분됩니다:

  • 로그인 안한 상태에서 요청할 때: 401 Unauthorized
  • Refresh Token 만료 됐을 때: 401 Unauthorized
  • Refresh Token이 DB에 저장된 것과 다를 때: 403 Forbidden