파일구조
구성형식
시작 설치 패키지
npx create-react-app my-app: React 앱의 기본 구조 생성npm install axios react-router-dom: 서버와 통신하거나 페이지 간 이동을 구현하기 위한 도구 설치생성 파일 구조
my-app/
├── node_modules/
├── public/
│ ├── index.html
│ ├── favicon.ico
├── src/
│ ├── App.js
│ ├── index.js
│ ├── App.css
│ ├── index.css
├── package.json
├── README.md
├── .gitignore
Login.js 파일 생성
로그인 페이지 UI를 구성, 사용자가 ID와 비밀번호 입력
import React, { useState } from 'react'; import './Login.css'; import SignupModal from './SignupModal';useState
- 입력한 값을 저장하는 "저장소" 역할
- 이메일과 비밀번호를 입력하면 값이 저장
try { const response = await fetch('http://localhost:3001/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }), }); const result = await response.text(); if (response.ok) { alert(result); // "로그인 성공" setIsAuthenticated(true); // 로그인 성공 시 상태 업데이트 } else { alert(result); // "로그인 실패" 또는 "사용자가 존재하지 않습니다." } } catch (error) { alert('로그인 중 오류 발생'); }
- 사용자가 로그인 버튼을 누르면 handleLogin 함수 실행
- 서버에 사용자가 입력한 이메일과 비밀번호를 보내서 맞는지 확인
- 맞으면 성공 메시지, 틀리면 실패 메시지
{showSignup && <SignupModal onClose={() => setShowSignup(false)} />}
- true 또는 false값을 가질 수 있음
- showSignup이 true면 팝업창을 보여주고, flase면 팝업창 숨김(기본값)
onClose={() => setShowSignup(false)
- 팝업창을 닫을 때 실행되는 함수
- 팝업창이 닫힐 때 호출해서 showSignup값을 다시 false로 바뀜
핵심코드
const Login = ({ setIsAuthenticated }) => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [showSignup, setShowSignup] = useState(false); const handleLogin = async (e) => { e.preventDefault(); // 로그인 요청 try { const response = await fetch('http://localhost:3001/login', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ email, password }), }); const result = await response.text(); if (response.ok) { alert(result); // "로그인 성공" setIsAuthenticated(true); // 로그인 성공 시 상태 업데이트 } else { alert(result); // "로그인 실패" 또는 "사용자가 존재하지 않습니다." } } catch (error) { alert('로그인 중 오류 발생'); } };-이메일&비밀번호 입력 후 폼을 제출 하면 이 함수 실행
- Fect 함수가 POST요청을 만들어 서버로 데이터 보냄
사용자가 입력한 이메일과 비밀번호는 JSON 형식으로 전송- 서버는 데이터를 받아 로그인
SignupModal.js
- 회원가입 버튼을 누르면 해당 팝업창 열림, 팝업창에서 사용자 정보 입력, 저장 기능 구현
- Modal 형태, 회원가입이 완료되면 팝업창 닫고 로그인 화면으로 돌아감
→ 이메일, 비밀번호 입력과 체크박스 선택 후 회원가입 버튼을 누르면 서버로 회원가입 요청을 보내고, 성공하면 팝업창을 닫는 기능을 하는 회원가입 팝업창
const SignupModal = ({ onClose }) => { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [isChecked1, setIsChecked1] = useState(false); const [isChecked2, setIsChecked2] = useState(false); const [isChecked3, setIsChecked3] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); // 로딩 상태 추가
useState
- 이메일, 비밀번호 확인, 체크박스 상태 저장
- 사용자가 입력하거나 클릭할 때 값 업데이트
handleSignup함수
- 체크박스가 모두 체크되었는지 확인
- 비밀번호, 비밀번호 확인이 일치하는지 확인
- 비밀번호 길이가 최소 8자인지 확인
조건이 모두 만족되면 회원가입 요청을 보내고 그 결과를 사용자가 확인onClose
팝업을 닫을 수 있는 닫기 버튼
server.js
- 서버와 데이터를 주고받는 부분을 담당하는 파일
- 로그인 시 저장된 정보를 서버에 보내거나, 회원가입 데이터를 저장하는 기능 처리
백엔드에서 서버를 설정하고, 로그인과 회원가입 요청을 처리하는 역할
클라이언트에서 입력한 정보를 백엔드에서 받아서 처리할 수 있도록 만듦
설치 패키지
npm install express
서버를 쉽게 만들 수 있게 도와주는 패키지
npm install mysql2
MySQL 데이터베이스와 연결하고, 데이터를 주고받을 수 있도록 도와주는 패키지
npm install bcrypt
비밀번호 암호화를 위한 패키지
npm install cors
1) CORS(Cross-Origin Resource Sharing) 문제를 해결하기 위한 패키지
2) 클라이언트와 서버가 다른 도메인에 있을 때, 클라이언트가 서버에 요청을 보낼 수 있도록 허용하는 역할
전체적인 흐름
회원가입 과정 (새로운 회원의 정보를 MySQL에 저장하는 과정)송마루
1) 사용자 입력
- 사용자가 회원가입 폼에 이메일과 비밀번호를 입력하고 “회원가입” 버튼을 누르면 React에서 데이터를 받아 처리
- React 상태로 폼에서 입력한 데이터를 관리한 후, 이 데이터를 서버로 POST요청을 통해 전송
2) React에서 서버로 POST 요청
- fect API를 사용하여 사용자가 입력한 데이터를 Node.js 서버로 POST 요청을 보냄
- 요청은 이메일과 비밀번호가 JSON형식으로 담겨 전송
3) Node.js 서버에서 데이터 처리
- Node.js 서버는 요청을 받으면 req.body에서 email과 password 값을 추출
- 비밀번호 그대로 저장하면 보안에 취약하기 때문에 bcrypt를 사용해 비밀번호를 암호화한 후 MySQL에 저장
- Bcrypt.hash 함수를 통해 비밀번호는 암호화된 상태로 데이터베이스에 저장(실제 데이터 볼 수 X)
로그인 과정 (저장된 데이터를 기반으로 인증하는 흐름)
1) 사용자 입력
- 사용자가 로그인 폼에 이메일과 비밀번호를 입력하고 로그인 버튼 클릭
- 입력된 정보는 POST 요청으로 서버에 전송
2) 서버에서 로그인 정보 처리
Node.js 서버는 POST요청을 받아 MySQL 데이터베이스에서 해당 이메일에 대한 정보를 가져옴3) 암호화된 비밀번호와 비교
- bcrypt.compare를 사용해 데이터베이스에 저장된 암호화된 비밀번호와 사용자가 입력한 비밀번호를 비교
- bcrypt.compare 함수는 입력된 평문 비밀번호를 암호화된 비밀번호와 비교하여 일치 여부를 판단
4) 로그인 성공/실패 처리
- 비밀번호가 일치하면 로그인 성공 메시지를 보내고, 그렇지 않으면 로그인 실패 메시지 전송
- 로그인 성공 시, React 애플리케이션에서는 사용자를 메인 페이지로 리디렉션하거나,
로그인 상태를 true로 업데이트하여 적절한 화면 보여줌
포트를 다르게 사용하는 이유
프론트엔드(React) - 3000번 포트
- React앱은 기본적으로 개발 중일 때 3000번 포트에서 실행
- 3000번 포트는 클라이언트 측, 즉 사용자가 브라우저에서 직접 접근하는 UI부분
- 사용자가 로그인/회원가입 폼에 접근하는 페이지가 이 포트에서 동작
- 이 페이지에서 사용자가 입력한 데이터를 처리해서 서버로 보내는 역할
백엔드(Node.js) - 3001번 포트
- Node.js 서버는 클라이언트가 요청한 데이터를 처리하고, 데이터베이스와 통신하는 서버 측 역할
- React와 별도로 3001번 포트에서 실행
- 클라이언트가(React)가 서버에 데이터를 보내기 위해서 POST 요청을 보내는 대상이 3001번 포트
- 예) 서용자가 로그인 정보를 입력하고 제출하면,
그 데이터가 3001번 포트에서 실행되는 서버로 전달 – 로그인 처리정리
예시)
- 프론트엔드와 백엔드는 서로 다른 환경에서 실행되기때문에 각기 다른 포트 사용
- 3000번 포트에서 실행되는 React 앱은 사용자와 상호작용하는 클라이언트 측
- 3001번 포트에서 실행되는 Node.js 서버는 클라이언트의 요청을 처리하는 백엔드 측
- 서로 다른 포트를 사용함으로써, 클라이언트와 서버 간에 명확한 구분 가능하고 둘 사이의 데이터를 주고받는 방식인 API 통신 사용 가능
React(3000번) : 클라이언트가 폼을 작성하고 로그인 버튼 클릭 → 입력 데이터를 3001번 포트의 서버로 전송
Node.js(3001번) : 서버는 클라이언트에서 받은 데이터를 처리하고, 로그인 성공/실패 여부를 다시 React(3000)에 돌려줌
로그인 성공시
- 초기 상태 : isAuthenticated가 false이기 때문에 로그인 화면이 보임
- 이 상태에서 메인 페이지는 보이지 않지만, 사용자가 로그인을 - 성공하면 setIsAuthenticated(true)를 호출
- 로그인 상태를 true로 변경
- 로그인 상태가 변경되면 메인페이지 표시
- 로그인 상태가 변경되면서 React는 자동으로 화면 다시그림
→ 로그인 화면이 사라지고, 그 뒤 메인 화면 나타냄
App.js
- React 애플리케이션의 전체 구조와 페이지 전환 담당
- 사용자가 로그인 했는지 여부 확인
- 그에 따라 로그인 페이지 또는 메인 페이지로 이동시켜 주는 것
- React Router를 사용하여 로그인된 사용자만 메인 페이지에 - 접근할 수 있도록 설정
- 그렇지 않은 경우 로그인 페이지로 리디렉션하는 방식으로 구현
index.js
- React 애플리케이션의 시작점 역할
- 우리가 만든 모든 컴포넌트를 브라우저에 실제로 보여주기하는 역할
- 이 파일이 없으면 우리가 만든 React 컴포넌트들이 브라우저에 표시되지 않음
설치 패키지
npm install react
React는 컴포넌트를 만들고 관리하는 주요 라이브러리
npm install react-dom
React로 만든 컴포넌트를 실제로 HTML 페이지에 렌더링하는 도구
npm install react-router-dom
페이지 간 네비게이션(라우팅)을 쉽게 구현할 수 있도록 도와줌