React에서 JWT 토큰 사용하기: 초보자를 위한 가이드
2024-10-10 19:27:48JWT란 무엇인가?
JWT(제이슨 웹 토큰, JSON Web Token)는 두 개의 주체 사이에서 정보를 안전하게 전송하기 위한 개방형 표준입니다. 간결하고 자가 포함된 형태로 정보를 전송할 수 있는 방법을 제공하여, 클라이언트와 서버 간의 신뢰성을 높이고 인증 작업을 용이하게 합니다.
JWT는 세 가지 주요 부분으로 구성됩니다:
- 헤더(Header): 토큰의 타입과 서명 알고리즘을 포함합니다.
- 페이로드(Payload): 사용자 정보와 같은 클레임을 포함합니다.
- 서명(Signature): 토큰이 변조되지 않았음을 보장합니다.
이러한 구조 덕분에 JWT는 상태 비저장(stateless) 인증을 구현하는 데 매우 유용합니다. 이 글에서는 React 애플리케이션에서 JWT를 사용하여 인증 및 세션 관리를 어떻게 구현할 수 있는지 알아보겠습니다.
JWT 사용의 장점
JWT는 현대 웹 애플리케이션에서 많이 사용됩니다. 그 이유는 다음과 같습니다:
- 상태 비저장 인증: JWT는 모든 사용자 정보를 포함하므로 서버가 상태를 유지할 필요가 없습니다. 이는 RESTful API에서 특히 유용합니다.
- 보안: JWT는 서명되기 때문에 클라이언트가 토큰을 변조할 수 없습니다.
- 휴대성: JWT는 문자열로 쉽게 전송할 수 있으며, HTTP 헤더, URL 매개변수 또는 로컬 스토리지에 저장할 수 있습니다.
React에서 JWT 사용하기
이제 JWT를 React 애플리케이션에 통합하는 방법을 단계별로 살펴보겠습니다.
1단계: 백엔드 설정
React 애플리케이션에서 JWT로 사용자를 인증하기 위해서는 JWT를 생성할 수 있는 백엔드가 필요합니다. 일반적으로 Node.js와 Express를 사용하여 JWT를 생성하고 검증하지만, 어떤 언어나 프레임워크를 사용해도 가능합니다.
다음은 Node.js에서 jsonwebtoken 패키지를 사용하여 JWT를 생성하는 예시입니다:
const jwt = require('jsonwebtoken');
const user = { id: 1, username: "exampleUser" };
const accessToken = jwt.sign(user, process.env.JWT_SECRET, { expiresIn: '1h' });
JWT는 사용자가 성공적으로 로그인한 후 프론트엔드로 전송됩니다.
2단계: React에 필요한 라이브러리 설치하기
React 앱에서 API 요청을 하기 위해 axios와 JWT를 디코딩하기 위한 jwt-decode 라이브러리를 설치합니다.
npm install axios jwt-decode
- Axios: 백엔드와 HTTP 요청을 보내기 위해 사용합니다.
- jwt-decode: JWT의 정보를 디코드하는 데 사용합니다.
3단계: 로그인 폼 만들기
사용자가 로그인 정보를 입력할 수 있는 기본 폼을 만듭니다. 사용자가 폼을 제출하면, 백엔드로 자격 증명이 전송되고, 유효하면 JWT가 반환됩니다.
import React, { useState } from 'react';
import axios from 'axios';
const Login = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleSubmit = async (e) => {
e.preventDefault();
try {
const response = await axios.post('http://localhost:5000/api/login', { email, password });
const { token } = response.data;
// 토큰을 로컬 스토리지에 저장
localStorage.setItem('token', token);
// 사용자 리다이렉션 또는 상태 업데이트
console.log('로그인 성공, 토큰 저장됨.');
} catch (error) {
console.error('로그인 실패:', error.response.data);
}
};
return (
<form onSubmit={handleSubmit}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="이메일"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="비밀번호"
/>
<button type="submit">로그인</button>
</form>
);
};
export default Login;
4단계: 토큰 저장하기
백엔드에서 JWT를 받으면, 이를 브라우저의 localStorage 또는 sessionStorage에 저장합니다. 여기서는 localStorage를 사용하며, 이는 브라우저가 종료된 후에도 유지됩니다.
localStorage.setItem('token', token);
하지만 XSS 공격에 취약할 수 있으므로, 생산 환경에서는 HTTP-Only 쿠키에 저장하는 것이 더 안전합니다.
5단계: 인증된 요청하기
토큰을 받으면, 이 토큰을 사용하여 백엔드의 보호된 경로에 접근하기 위해 요청 헤더에 포함합니다.
const getUserProfile = async () => {
const token = localStorage.getItem('token');
if (token) {
try {
const response = await axios.get('http://localhost:5000/api/profile', {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(response.data);
} catch (error) {
console.error('프로필 가져오기 실패:', error);
}
}
};
6단계: JWT 디코딩
JWT에 저장된 사용자 정보를 액세스해야 하는 경우, jwt-decode를 사용하여 JWT를 디코드할 수 있습니다.
import jwt_decode from 'jwt-decode';
const token = localStorage.getItem('token');
if (token) {
const decoded = jwt_decode(token);
console.log('디코딩된 토큰:', decoded);
}
이렇게 하면, 토큰에 저장된 사용자ID, 역할 등의 정보가 출력됩니다.
7단계: 로그아웃 구현하기
사용자를 로그아웃하려면, 로컬 스토리지에서 JWT를 삭제하면 됩니다.
const logout = () => {
localStorage.removeItem('token');
console.log('사용자가 로그아웃되었습니다.');
};
8단계: 토큰 만료 및 갱신
JWT는 일반적으로 만료 시간을 설정합니다(exp 클레임). 토큰이 만료되면, 사용자에게 새 토큰을 요청하거나 재로그인을 요구할 수 있습니다.
결론
위의 단계에 따라 JWT를 React 애플리케이션에 통합하면, 안전하고 효율적인 사용자 인증 및 세션 관리를 구현할 수 있습니다. JWT는 상태 비저장 인증을 가능하게 하며, 클라이언트와 서버 간의 보안을 강화해줍니다.
JWT 사용 시, 보안상의 이유로 적절한 저장소를 선택하고 토큰을 주기적으로 갱신하는 것이 중요합니다. 이 가이드를 따라 React 애플리케이션에서 JWT를 활용하여 더욱 안전한 웹 서비스를 구축해보세요.
참고 자료
이 글이 React에서 JWT를 사용하는 데 유용한 자료가 되기를 바랍니다. 추가 질문이나 의견이 있으시면 언제든지 댓글로 남겨주세요!