<React + Vue.js> 프로젝트 내 로그인 기능 구현 가이드 With Dummy Server
1. 서론
이번 글에서는 React 로그인 기능을 구현하는 방법을 다룹니다. 사용자로부터 이메일과 비밀번호를 입력받아 서버와 통신하여 로그인 요청을 처리하고, 응답을 받아 인증 상태를 관리하는 과정을 단계별로 설명합니다. 이 가이드에서는 비밀번호 유효성 검사, 로딩 상태 관리, 예외 처리 등을 포함하여 완성된 로그인 페이지를 만들어 보겠습니다.
중요한 점은 이 글은 실제 API가 아닌, Dummy API로 Test 용 서버를 가지고 로그인 및 회원가입의 정상적인 흐름을 확인하는 것 뿐이라는 것을 분명히 명시합니다.
2. 주요 기능
• 입력 필드 관리: useState로 입력값 상태를 관리하여 폼 제출 시 데이터를 전송합니다.
• 서버 통신: axios를 사용하여 로그인 요청을 처리합니다.
• 에러 메시지 출력: 잘못된 로그인 시 에러 메시지를 표시합니다.
• 로딩 상태: 요청 중 로딩 상태를 시각적으로 표시합니다.
• 토큰 저장 및 인증: 로그인 성공 시 토큰을 저장하여 사용자 인증 상태를 관리합니다.
3. 로그인 페이지 컴포넌트 단계별 구현
Step 1. 상태 선언 및 입력값 관리
로그인 페이지에서 useState를 사용하여 이메일과 비밀번호를 관리합니다.
코드 예제:
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false); // 로딩 상태
• email: 이메일 입력 상태
• password: 비밀번호 입력 상태
• error: 로그인 실패 시 에러 메시지
• loading: 로딩 상태 관리
Step 2. 입력 이벤트 핸들러 작성
입력값이 변경될 때 onChange 이벤트 핸들러로 상태를 업데이트합니다.
코드 예제:
const handleEmailChange = (e) => setEmail(e.target.value);
const handlePasswordChange = (e) => setPassword(e.target.value);
Step 3. 로그인 요청 처리
**axios.post()**를 사용하여 서버에 로그인 요청을 보냅니다.
코드 예제:
const handleLoginSubmit = async (e) => {
e.preventDefault(); // 기본 동작 방지
setLoading(true); // 로딩 상태 활성화
try {
const response = await axios.post('http://localhost:3001/login', {
email,
password,
});
const token = response.data.token; // 서버에서 받은 JWT 토큰
localStorage.setItem('authToken', token); // 토큰 저장
alert('로그인 성공! 환영합니다!');
setError('');
} catch (e) {
setError('아이디 또는 비밀번호가 잘못되었습니다.');
} finally {
setLoading(false); // 로딩 상태 해제
}
};
• axios.post(): 서버에 로그인 정보를 전송합니다.
• localStorage.setItem(): 받은 토큰을 localStorage에 저장하여 인증 상태를 유지합니다.
Step 4. 로그인 페이지 UI 작성
입력 필드를 사용하여 이메일과 비밀번호를 입력받고, 버튼 클릭 시 handleLoginSubmit 함수를 호출합니다.
코드 예제:
<form onSubmit={handleLoginSubmit}>
<input
type="email"
placeholder="이메일"
value={email}
onChange={handleEmailChange}
required
/>
<input
type="password"
placeholder="비밀번호"
value={password}
onChange={handlePasswordChange}
required
/>
{error && <p style={{ color: 'red' }}>{error}</p>}
<button type="submit" disabled={loading}>
{loading ? '로그인 중...' : '로그인'}
</button>
</form>
• value={state}: 입력 필드에 상태를 바인딩합니다.
• onChange 이벤트 핸들러: 입력값이 변경될 때 상태를 업데이트합니다.
• disabled={loading}: 로딩 중에는 버튼을 비활성화하여 중복 요청을 방지합니다.
4. 로그인 후 페이지 이동 (useNavigate)
로그인 성공 시 메인 페이지로 이동하기 위해 **useNavigate**를 사용합니다.
라우터를 활용하는 방식을 선호하기에 만일 Next.js 환경에서 작업하신다면 굳이 필요는 없을수도 있습니다.
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate(); // 페이지 이동 훅
const handleLoginSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
const response = await axios.post('http://localhost:3001/login', { email, password });
const token = response.data.token;
localStorage.setItem('authToken', token);
navigate('/home'); // 홈 페이지로 이동
} catch (e) {
setError('로그인 실패! 다시 시도해주세요.');
} finally {
setLoading(false);
}
};
• useNavigate: React Router v6의 페이지 이동 훅입니다.
• 로그인 성공 시 /home 페이지로 이동합니다.
5. 인증 요청 및 보호된 페이지 접근 ( Dummy Server에서는 활용 안할 것임)
서버로 인증이 필요한 요청을 보낼 때, Authorization 헤더에 토큰을 포함합니다.
이 방법은 JWT를 활용한 실제 서버에서 활용하는 방법입니다.
간략한 예시 코드만 작성하겠습니다.
코드 예제:
const handleProtectedRequest = async () => {
const token = localStorage.getItem('authToken');
try {
const response = await axios.get('http://localhost:3001/protected', {
headers: { Authorization: `Bearer ${token}` },
});
console.log('인증 성공:', response.data);
} catch (error) {
console.error('인증 실패:', error);
}
};
6. 로그인 기능 전체 코드
LoginPage.js
import React, { useState } from 'react';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
const LoginPage = () => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [loading, setLoading] = useState(false);
const navigate = useNavigate();
const handleLoginSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
const response = await axios.post('http://localhost:3001/login', { email, password });
const token = response.data.token;
localStorage.setItem('authToken', token);
alert('로그인 성공!');
navigate('/home');
} catch (error) {
setError('아이디 또는 비밀번호가 잘못되었습니다.');
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleLoginSubmit}>
<input
type="email"
placeholder="이메일"
value={email}
onChange={(e) => setEmail(e.target.value)}
required
/>
<input
type="password"
placeholder="비밀번호"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
/>
{error && <p style={{ color: 'red' }}>{error}</p>}
<button type="submit" disabled={loading}>
{loading ? '로그인 중...' : '로그인'}
</button>
</form>
);
};
export default LoginPage;
결론
이제 React 로그인 페이지를 완성했습니다!
로그인 기능 구현 시에는 반드시 서버와의 통신 및 에러 처리를 신경 써야 합니다. 또한, JWT 토큰을 활용한 인증 시스템으로 보안 강화를 할 수 있습니다.
이것은 기본 프로토타입에 불과합니다. 더더욱 발전시켜서 완전한 프로젝트를 만들어보겠습니다.