반응형
1. 개요
JWT(JSON Web Token)는 서버가 사용자를 인증한 후 클라이언트에게 토큰을 발급하여, 클라이언트가 이후 요청 시 토큰을 포함시켜 인증 상태를 유지하도록 하는 방식이다. React와 같은 SPA(Single Page Application)에서는 이 토큰을 활용해 사용자의 로그인/로그아웃 상태를 관리할 수 있다.
JWT의 기본 개념, React 내에서의 인증 상태 관리, 그리고 로그아웃 구현 로직에 대해
알아보자.
2. JWT 인증 흐름
- 로그인 과정
- 사용자가 로그인 폼에 자격 증명을 입력하면, 백엔드 서버는 해당 정보를 검증
- 인증에 성공하면 서버는 사용자의 정보를 포함한 JWT를 생성하여 클라이언트에 전달
- 클라이언트는 이 토큰을 안전한 저장소(예: localStorage, sessionStorage 또는 보안 쿠키)에 저장
(보안상의 이유로 XSS 공격에 취약할 수 있는 localStorage 대신 httpOnly 쿠키 사용 고려 가능)
- 인증된 요청
- 클라이언트는 이후의 API 요청 시 JWT를 HTTP 헤더(주로 Authorization: Bearer <토큰>)에 포함하여 전송
- 서버는 요청마다 JWT의 유효성을 확인하고, 인증이 필요한 리소스에 대한 접근 권한을 부여
- 토큰 갱신 및 만료
- JWT에는 보통 만료 시간이 포함되어 있어, 만료 시 재인증이나 리프레시 토큰을 통해 새로운 JWT를 발급이 가능
3. React 애플리케이션에서의 인증 구현
3.1 전역 상태 관리
- React에서는 Context API나 Redux와 같은 상태 관리 라이브러리를 활용하여 인증 상태를 전역으로 관리
- 예를 들어, AuthContext를 생성하여 로그인, 로그아웃, 그리고 사용자 정보 등의 관리가 가능
3.2 토큰 저장 및 사용
- 저장 위치:
- localStorage: 간단하지만 XSS 공격에 취약할 수 있음
- httpOnly 쿠키: 스크립트 접근이 불가능하여 보안성이 높음
- 요청 시 토큰 사용:
Axios나 Fetch API를 사용할 때 인터셉터(interceptor)를 설정하여, 모든 요청에 JWT를 자동으로 포함시킬 수 있음
4. 로그아웃 구현 로직
로그아웃은 기본적으로 클라이언트 측에서 JWT를 제거하고, 인증 상태를 업데이트하는 방식으로 구현
4.1 클라이언트 측 로그아웃
- 토큰 삭제:
- 사용자가 로그아웃 버튼을 클릭하면 localStorage(또는 해당 저장소)에서 JWT를 삭제
- 상태 초기화:
- 전역 인증 상태(예: user 또는 isAuthenticated)를 초기화하여 사용자가 더 이상 인증된 상태로 간주되지 않도록 함
- UI 업데이트:
- 로그인 페이지로 리다이렉션하거나, 사용자 관련 데이터를 초기화
예시 코드
// AuthContext.js
import React, { createContext, useState, useEffect } from 'react';
export const AuthContext = createContext();
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
// 초기 토큰 존재 여부 확인
const token = localStorage.getItem('token');
if (token) {
// 필요한 경우 토큰 검증 및 사용자 정보 복호화
setUser({ token });
}
}, []);
const login = (token) => {
localStorage.setItem('token', token);
setUser({ token });
};
const logout = () => {
// 토큰 제거 및 인증 상태 초기화
localStorage.removeItem('token');
setUser(null);
// 필요 시 애플리케이션 캐시나 기타 상태 초기화
};
return (
<AuthContext.Provider value={{ user, login, logout }}>
{children}
</AuthContext.Provider>
);
};
4.2 서버 측 고려사항
- 토큰 블랙리스트 처리:
서버에서 JWT 자체는 상태를 갖지 않는(stateless) 방식이므로, 단순히 클라이언트가 토큰을 삭제하는 것으로 로그아웃 처리 가능 - 하지만 보안 강화가 필요한 경우, 서버 측에서 JWT를 블랙리스트에 추가하여 더 이상 해당 토큰을 사용할 수 없도록 할 수 있음
- 세션 관리:
만약 httpOnly 쿠키를 사용한다면, 로그아웃 시 서버에서 쿠키를 삭제하거나 만료시키는 API를 호출할 수 있음
5. 추가 고려사항
- 보안 강화:
- XSS 공격으로부터 토큰을 보호하기 위해 httpOnly 쿠키 사용을 고려
- CSRF 공격에 대비하여 CSRF 토큰 사용 또는 SameSite 쿠키 속성 설정
- 토큰 만료 및 갱신:
- JWT 만료 시간에 따른 자동 로그아웃 기능 구현
- 리프레시 토큰을 활용하여 만료된 토큰을 갱신하는 로직 추가
- 에러 처리:
- 만약 토큰이 만료되었거나 유효하지 않은 경우, API 응답에 따라 자동 로그아웃 처리 및 사용자에게 재로그인을 요청하는 UI 제공
6. 결론
- React 애플리케이션에서 JWT 기반 인증 시스템은 클라이언트와 서버 간의 안전한 통신을 보장하면서 사용자의 로그인 상태를 효과적으로 관리할 수 있는 방법
- 로그아웃 구현은 주로 클라이언트 측에서 JWT를 제거하고 전역 인증 상태를 업데이트하는 방식으로 진행되며, 보안 요구사항에 따라 서버 측에서 추가적인 토큰 무효화 로직을 적용할 수도 있음
반응형
'개발이야기 > 웹개발' 카테고리의 다른 글
[코드잇 스프린트 풀스택 4기] OAuth의 개념과 사용 이유 (0) | 2025.03.30 |
---|---|
[코드잇 스프린트 풀스택 4기] RESTful API의 개념과 주요 제약 조건 (0) | 2025.03.30 |
[코드잇 스프린트 풀스택 4기] 세션 기반 인증과 토큰 기반 인증 (0) | 2025.03.30 |
[코드잇 스프린트 풀스택 4기] Next.js를 사용하는 이유 (0) | 2025.01.20 |
[코드잇 스프린트 풀스택 4기] 웹 페이지 랜더링 방식 CSR, SSR, SSG (1) | 2025.01.20 |