JWT와 React 인증 구현
1. JWT 개념 및 작동 원리
JWT(JSON Web Token)*는 서버와 클라이언트 간의 안전한 사용자 인증을 위해 사용되는 암호화된 토큰입니다.
사용자가 로그인하면 서버는 사용자의 정보를 기반으로 JWT를 생성하고 클라이언트에 전달합니다.
이후 클라이언트는 서버로 요청을 보낼 때 이 JWT를 HTTP 헤더에 포함시켜 인증을 수행합니다.
JWT 구조:
Header.Payload.Signature- Header: 토큰 유형(JWT) 및 서명 알고리즘(HMAC SHA256, RSA 등) 정보
- Payload: 사용자 정보 및 토큰 만료 시간 등 Claims 데이터
- Signature: 토큰 위변조 방지를 위한 서명 값
작동 흐름
- 사용자가 로그인 요청
- 서버가 사용자 정보를 검증 후 JWT 발급
- 클라이언트가 토큰을 저장(localStorage, sessionStorage, 쿠키 등)
- API 요청 시
Authorization: Bearer <token>헤더에 첨부 - 서버에서 JWT의 유효성을 검증 후 요청 처리
2. React 애플리케이션에서 JWT 구현 절차
React에서 JWT를 사용하는 기본 인증 흐름은 다음과 같습니다.
- 로그인 폼 작성 → 서버로 사용자 ID/비밀번호 전송
- 서버에서 사용자 검증 후 Access Token + Refresh Token 발급
- 클라이언트에서 토큰 저장 (localStorage, sessionStorage, 또는 HttpOnly 쿠키)
- API 요청 시 Axios 인터셉터 또는 Fetch API를 사용해 자동으로 토큰을 헤더에 포함
- Access Token이 만료되면 Refresh Token으로 새로운 토큰 발급
- 로그아웃 시 클라이언트 측에서 저장된 토큰 제거
3. 클라이언트에서 JWT 저장 방식
JWT를 클라이언트에 저장하는 방법은 보안성과 직결됩니다. 각 방식의 장단점은 다음과 같습니다.
저장 방식 설명 보안성 권장 여부 localStorage 구현 간단, 새로고침해도 유지됨 XSS 공격에 취약 ❌ 비권장 sessionStorage 브라우저 세션 단위 저장, 탭 닫으면 삭제됨 XSS 공격에 여전히 취약 ⚠️ 제한적 사용 HttpOnly 쿠키 JS에서 접근 불가, Secure/SameSite 옵션 사용 가능 XSS·CSRF 방어 가능 ✅ 권장 메모리 저장 브라우저 메모리에만 저장, 탭 닫으면 삭제됨 가장 안전하지만 새로고침 시 상태 유지 불가 ⚠️ SPA 전용 사용 권장 방식: HttpOnly + Secure + SameSite 쿠키를 사용하는 방법입니다.
4. API 요청 시 JWT 활용
API 요청 시 JWT를 사용하는 가장 보편적인 방식은 Authorization 헤더를 활용하는 것입니다.
Axios 인터셉터 예시:
import axios from 'axios'; axios.interceptors.request.use(config => { const token = localStorage.getItem('accessToken'); if (token) config.headers.Authorization = `Bearer ${token}`; return config; });이렇게 설정하면 Axios를 통한 모든 API 요청에 JWT가 자동으로 포함되어 보안성과 편리성을 동시에 확보할 수 있습니다.
5. 로그아웃 로직 구현 및 이유
토큰 기반 인증은 서버가 세션을 관리하지 않는 stateless 구조이므로, 로그아웃 시 서버에서 세션을 삭제할 필요가 없습니다.
대신 클라이언트에서 토큰을 제거하는 방식으로 로그아웃을 구현합니다.
- 로그아웃 절차
- localStorage / sessionStorage / 쿠키에서 토큰 삭제
- Refresh Token을 사용하는 경우, 서버에 폐기 요청 가능
- 이유
- JWT 자체에 사용자 정보가 들어 있으므로 토큰 제거만으로 인증 무효화 가능
- 서버 부하를 최소화하면서 효율적인 로그아웃 처리 가능
6. 클라이언트에서 토큰 제거 프로세스
React에서 로그아웃 버튼 클릭 시 토큰을 제거하는 예시는 다음과 같습니다.
const handleLogout = () => { localStorage.removeItem('accessToken'); localStorage.removeItem('refreshToken'); delete axios.defaults.headers.common['Authorization']; navigate('/login'); };이 과정을 통해 클라이언트 측 저장소에서 토큰을 삭제하고, 인증되지 않은 상태로 되돌릴 수 있습니다.
7. 보안을 위한 추가 조치
JWT 기반 인증에서 보안을 강화하기 위해 다음과 같은 조치를 권장합니다.
- 쿠키 보안 속성 설정
HttpOnly,Secure,SameSite=Strict
- 짧은 Access Token 만료 시간 → 공격 시 피해 최소화
- Refresh Token 기반 토큰 갱신 구조 활용
- 민감한 작업 시 2FA(이중 인증) 또는 OTP 적용
- 모든 요청은 반드시 HTTPS 프로토콜로 전송
요약
구분 핵심 내용 권장 방식 JWT 개념 사용자 인증을 위한 암호화 토큰 Header.Payload.Signature 구조 React 구현 로그인 → 토큰 발급 → 저장 → API 인증 → 갱신 → 로그아웃 Axios 인터셉터 활용 저장 방식 HttpOnly 쿠키 권장 Secure + SameSite 옵션 병행 API 인증 Authorization 헤더에 JWT 첨부 Bearer 토큰 방식 로그아웃 클라이언트 측에서 토큰 제거 Refresh Token 폐기 가능 보안 강화 HttpOnly, Secure, HTTPS, OTP 등 사용 JWT + Refresh Token 구조 JWT 인증 흐름
[1] 로그인 요청 ↓ (아이디/비밀번호) [2] 서버에서 사용자 인증 ↓ (성공 시) [3] Access Token + Refresh Token 발급 ↓ [4] 클라이언트 저장 ├─ localStorage (단순) ├─ sessionStorage (세션 단위) └─ HttpOnly 쿠키 (**권장**) ↓ [5] API 요청 시 Authorization 헤더에 JWT 첨부 ↓ [6] 서버에서 토큰 검증 → 성공 시 데이터 반환 ↓ [7] 토큰 만료 시 Refresh Token으로 갱신 ↓ [8] 로그아웃 시 클라이언트에서 토큰 제거요약
- JWT는 Header.Payload.Signature 구조로, 토큰 자체에 사용자 정보와 인증 상태를 담음
- React에서는 로그인 → 토큰 발급 → 저장 → API 요청 시 헤더 첨부 → 로그아웃 시 삭제 흐름
- 보안을 위해 HttpOnly + Secure 쿠키 사용을 적극 권장
- Access Token은 짧게, Refresh Token으로 재발급하는 구조가 가장 안전
카테고리 없음
[10주차] 위클리 페이퍼 - 경험을 바탕으로 React 애플리케이션에서 JSON Web Token(JWT)을 사용하여 사용자 인증 시스템을 구현하는 방법에 대해 자세히 설명해주세요. 특히 로그아웃 구현 로직에 대해 설명해주세요.
728x90
728x90