- Published on
JWT (JSON Web Tokens)
- Authors
- Name
- Hyo814
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 토큰이 만료되었을 때 이를 처리하는 방법에 대해 알아보겠습니다. 이 과정은 다음과 같은 단계로 이루어집니다:
- Access 토큰 만료 확인: 서버에서 응답 코드로 토큰 만료를 알립니다. 보통 HTTP status 401 (Unauthorized)을 사용합니다.
- Refresh 토큰으로 새 Access 토큰 요청: 만료된 Access 토큰을 갱신하기 위해 Refresh 토큰을 사용합니다. Refresh 토큰은 상대적으로 긴 유효기간을 가지며, 이를 사용해 새로운 Access 토큰을 발급받습니다.
- 새로운 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