React + FastAPI로 JWT 인증 기반 이벤트 관리 시스템 만들기

2025. 5. 23. 00:32·React

React + FastAPI로 JWT 인증 기반 이벤트 관리 시스템 만들기

1. 개요

React와 FastAPI를 연동하여 JWT 인증 기반 로그인 시스템을 구축하고, 인증된 사용자만 이벤트를 등록할 수 있게 했습니다. 추가로 이미지를 업로드하고 다운로드하는 기능도 구현했습니다.

📁 구조
├── frontend (React + Vite)
│   ├── App.jsx
│   ├── user/Login.jsx
│   └── event/Regist.jsx, List.jsx, Detail.jsx
└── backend (FastAPI)
    ├── main.py
    ├── routes/users.py, events.py
    ├── models/users.py, events.py
    └── uploads/

2. FastAPI - JWT 기반 로그인 구현

사용자 로그인 시 JWT 토큰을 발급하고, 이후 API 요청에는 Authorization: Bearer <token> 헤더를 통해 인증을 처리합니다.

@user_router.post("/signin")
async def sign_in(data: OAuth2PasswordRequestForm = Depends(), session = Depends(get_session)):
    user = session.exec(select(User).where(User.email == data.username)).first()
    if not user or not hash_password.verify_password(data.password, user.password):
        raise HTTPException(status_code=401, detail="로그인 실패")
    return {
        "access_token": create_jwt_token(user.email, user.id),
        "username": user.username
    }

3. React - 로그인 요청 및 토큰 저장

로그인 성공 시 JWT 토큰을 sessionStorage에 저장합니다.

axios.post("http://localhost:8000/users/signin", { username, password })
  .then((res) => {
    sessionStorage.setItem("token", res.data.access_token);
    navigate("/list");
  });

4. 이벤트 등록 - 이미지 포함 FormData 전송

React에서 FormData를 구성해 텍스트와 파일을 함께 전송합니다.

const formData = new FormData();
formData.append("title", form.title);
formData.append("description", form.description);
formData.append("tags", form.tags);
formData.append("location", form.location);
formData.append("image", imageFile);

axios.post("http://localhost:8000/events/", formData, {
  headers: {
    "Content-Type": "multipart/form-data",
    Authorization: `Bearer ${token}`
});

5. FastAPI - 이미지 저장 및 DB 기록

업로드된 이미지는 지정된 디렉터리에 저장하고, DB에는 파일명만 저장합니다.

file_path = FILE_DIR / image.filename
with open(file_path, "wb") as f:
    f.write(await image.read())

event = Event(..., image=image.filename)
session.add(event)

6. 이미지 다운로드 구현

이벤트 ID를 기반으로 파일명을 조회하고, 파일을 다운로드 응답으로 반환합니다.

@event_router.get("/download/{event_id}")
async def download_image(event_id: int):
    event = session.get(Event, event_id)
    file_path = FILE_DIR / event.image
    if not file_path.exists():
        raise HTTPException(404, "파일 없음")
    return FileResponse(path=file_path, filename=event.image)

7. 공통 레이아웃 및 로그인 여부 조건 처리

Layout 컴포넌트를 통해 로그인 여부에 따라 상단 메뉴와 라우팅을 제어합니다.

useEffect(() => {
  const token = sessionStorage.getItem("token");
  setIsLogin(!!token);
  navigate(token ? "/list" : "/login");
}, []);

return (
  <header>
    {isLogin ? <a onClick={handleLogout}>로그아웃</a> : <Link to="/login">로그인</Link>}
  </header>
);

 

전체 흐름과 핵심 포인트

전체 구현 흐름

  • 1단계: FastAPI에서 사용자 인증 로직(JWT 기반) 구현
  • 2단계: React에서 로그인 폼 구현 및 JWT 토큰 sessionStorage 저장
  • 3단계: 이벤트 등록 기능 구현 (FormData를 통해 이미지 포함 전송)
  • 4단계: FastAPI에서 이미지 파일 저장 + DB에 파일명 기록
  • 5단계: React 목록 컴포넌트에서 이미지 조회 및 다운로드 처리
  • 6단계: 공통 레이아웃 구성 및 로그인 여부에 따른 UI 렌더링 처리

핵심 구현 포인트

  • JWT 토큰을 발급하여 클라이언트 인증 상태를 유지
  • FormData를 통해 이미지 파일과 텍스트 데이터를 함께 전송
  • UploadFile로 받은 파일을 FastAPI에서 저장하고 파일명을 DB에 기록
  • FileResponse를 활용하여 이미지 다운로드 처리
  • sessionStorage에 저장된 토큰을 기반으로 로그인 상태 유지
  • React Router의 중첩 라우팅 + Outlet으로 공통 레이아웃 적용

반드시 기억해야 할 부분

  • 로그인 시 저장하는 키는 token으로 통일하고, 헤더에 Authorization: Bearer로 전달
  • 이미지는 파일명만 DB에 저장하고, 실제 파일은 서버 경로에 따로 저장
  • 다운로드 시 파일 경로 = 업로드 경로 + DB의 파일명이 정확히 일치해야 함
  • 라우팅 구조는 <Route path="/" element=<Layout />> 기반으로 구성
  • 공통 컴포넌트에서 로그인 여부 체크 및 navigate()로 페이지 제어

'React' 카테고리의 다른 글

React - Router  (0) 2025.05.20
React - props, 이벤트 핸들러  (0) 2025.05.20
React - JSX - 기초 문법  (0) 2025.05.19
React - Vite를 사용한 React 앱 개발  (0) 2025.05.19
'React' 카테고리의 다른 글
  • React - Router
  • React - props, 이벤트 핸들러
  • React - JSX - 기초 문법
  • React - Vite를 사용한 React 앱 개발
jaeon.cloud
jaeon.cloud
  • jaeon.cloud
    JEONG JAE ON
    jaeon.cloud
  • 전체
    오늘
    어제
    • 분류 전체보기 (60)
      • Docker (8)
      • Cloud (7)
      • AWS (14)
      • Network (9)
      • Linux (1)
      • Python (7)
      • Javascript (3)
      • React (5)
      • Project (3)
      • Kubernetes (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • GitHub
  • 공지사항

  • 인기 글

  • 태그

    kubernetes
    3-tier Architecture
    http
    클라우드
    네트워크
    AWS
    lambda
    cors
    react
    Python
    docker
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
jaeon.cloud
React + FastAPI로 JWT 인증 기반 이벤트 관리 시스템 만들기
상단으로

티스토리툴바