본문 바로가기
Programming

JWT에서 Refresh Token은 어떻게 넘겨주나?

by 가우리언 2024. 12. 26.
728x90
반응형

JWT에서 Refresh Token을 전달하는 방식은 구현 목적, 보안 요구 사항, 클라이언트-서버 간 통신 방식에 따라 다양합니다. 일반적으로 두 가지 주요 방식이 사용됩니다:


1. HTTP-Only Cookie로 전달

이 방법은 가장 안전한 방법 중 하나로, Refresh Token을 HTTP-Only 쿠키에 저장하고, 클라이언트가 자동으로 서버로 전송하도록 설정합니다.

장점:

  • XSS(Cross-Site Scripting) 공격에 안전합니다.
  • 브라우저가 자동으로 쿠키를 관리하므로 클라이언트 코드에서 Refresh Token을 다룰 필요가 없습니다.

구현 예시:

(1) 서버에서 쿠키 설정:

res.cookie('refreshToken', token, {
    httpOnly: true, // JavaScript로 접근 불가
    secure: true, // HTTPS에서만 전송
    sameSite: 'Strict', // Cross-site 요청 제한
    maxAge: 7 * 24 * 60 * 60 * 1000 // 7일 (만료 시간 설정)
});
res.json({ accessToken });

(2) 클라이언트에서 액세스 토큰 요청:

const response = await fetch('/refresh-token', {
    method: 'POST',
    credentials: 'include' // 쿠키를 포함하여 요청
});
const data = await response.json();
반응형

2. API 응답 바디로 전달

이 방식에서는 Refresh Token을 API 응답의 바디에 포함하여 전달하고, 클라이언트가 이를 로컬 스토리지나 메모리에 저장합니다.

장점:

  • 설정이 단순하고 서버 쿠키 설정 없이도 구현 가능.

단점:

  • 보안 취약점이 더 큽니다. 특히, XSS 공격 시 Refresh Token이 노출될 수 있습니다.

구현 예시:

(1) 서버에서 응답으로 전달:

res.json({
    accessToken,
    refreshToken
});

(2) 클라이언트에서 토큰 저장 및 요청:

const { accessToken, refreshToken } = await response.json();
localStorage.setItem('refreshToken', refreshToken);

// 토큰 갱신 시 사용
const refreshResponse = await fetch('/refresh-token', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({ refreshToken: localStorage.getItem('refreshToken') })
});
const newAccessToken = await refreshResponse.json();
728x90

추천 방식

  • HTTP-Only 쿠키 방식은 보안이 중요한 애플리케이션에서 권장됩니다.
  • API 바디 방식은 단순하고 빠르게 구현할 수 있지만, 보안이 취약해질 수 있으므로 일반적으로 추천되지 않습니다.

추가 보안 팁

  • Refresh Token의 만료 시간을 적절히 설정하세요.
  • Refresh Token 탈취를 방지하기 위해 IP 주소, User-Agent 등의 클라이언트 정보를 검증하세요.
  • 가능한 경우 Refresh Token 재사용 방지(Reuse Detection)를 구현하세요.
728x90
반응형