FastAPI - MiniProject - 정리

김기훈·2025년 10월 31일

부트캠프 프로젝트

목록 보기
8/39

구현 목표

나만의 일기장 만들기

일기를 작성하며 자신의 생각 정리 명언자기성찰 질문랜덤으로 제공하는 개인 일기 관리 서비스

필요한 작업

  • github - organizations - 브랜치 나누기

  • DB / 환경변수 설정

  • 회원가입

    • 로그인/로그아웃 (JWT 인증)
      • JWT 인증으로 로그인
  • 일기 CRUD

    • 일기 검색 및 정렬
  • 명언/자기성찰 질문 랜덤 제공

    • 웹 스크래핑으로 명언/자기성찰 질문 쓸어와서 DB에 저장 후 랜덤으로 불러오기
      • 북마크 기능 구현

내가 해야하는 일

  • FastAPI 프로젝트 초기 세팅
  • GitHub 레포 생성 및 브랜치 전략 관리

공통 작업

  • DB / DB 모델 설계 / 배포 / 프로젝트 세부 기획

사전 공부 필요한 것

  • 스크래핑
  • git 명령어
  • PostgreSQL
  • FastAPI JWT

실제 서비스 기준 인증 확장 포인트

  • JWT + Blacklist 구조는 "학습용"
    • 실무에서는 여러가지 개념이 추가됨
개념역할
Access Token / Refresh Token짧은 만료시간 + 자동 재발급
CSRF브라우저 환경 보호 (JWT 쿠키 보관 시)
OAuth2 Social LoginGoogle, Kakao 등 외부 로그인
Dependency Override테스트 시 가짜 사용자 주입

구조

큰 틀에서의 구조

fastapi_mini_project/
├── app/
│   ├── api/              # FastAPI 라우터 (엔드포인트)
│   ├── core/             # 공통 설정, 보안, 의존성 (Config, JWT, Password 등)
│   ├── models/           # Tortoise ORM 모델 (DB 테이블 정의)
│   ├── schemas/          # Pydantic 스키마 (요청/응답 데이터 검증)
│   ├── services/         # 비즈니스 로직 (회원가입, 로그인, CRUD 처리)
│   ├── repositories/     # DB 접근 로직 (CRUD 메서드)
│   ├── db/               # DB 연결 및 마이그레이션 설정
│   ├── scraping/         # 스크래핑 기능 (명언/질문 수집용)
│   ├── main.py           # FastAPI 진입점 (앱 실행 및 라우터 등록)
│   └── __init__.py
├── tests/                # 테스트 코드
├── .env / .env.dev       # 환경변수
├── pyproject.toml        # Poetry 설정
└── README.md             # 프로젝트 설명
폴더주요 역할예시 파일
api/실제로 클라이언트 요청이 들어오는 엔드포인트 정의auth.py, diary.py
core/앱의 핵심 설정 (DB URL, JWT, 암호화 등)config.py, security.py, dependencies.py
models/데이터베이스 테이블 정의 (Tortoise ORM 모델)user.py, diary.py
schemas/요청(Request) / 응답(Response) 검증용 모델 (Pydantic)user.py
services/핵심 비즈니스 로직 (회원가입, 로그인 등)auth_service.py
repositories/DB 조작 담당 (CRUD 기능 구현)user_repo.py
db/DB 연결 및 마이그레이션 관련base.py, session.py
scraping/외부 웹 데이터 수집 기능quote_scraper.py
tests/pytest 등으로 테스트 실행test_auth.py
main.pyFastAPI 앱 실행, 라우터 등록, DB 초기화

상세 구조

fastapi_mini_project/
├── app/
│   ├── api/
│   │   └── v1/
│   │       ├── auth.py
│   │       ├── diary.py
│   │       ├── quote.py
│   │       ├── question.py
│   │       └── __init__.py
│   │
│   ├── core/
│   │   ├── config.py
│   │   ├── security.py
│   │   ├── dependencies.py   
│   │   └── __init__.py
│   │
│   ├── models/
│   │   ├── user.py
│   │   ├── diary.py
│   │   ├── quote.py
│   │   ├── question.py
│   │   ├── bookmark.py
│   │   ├── token_blacklist.py
│   │   ├── user_question.py
│   │   └── __init__.py
│   │
│   ├── schemas/
│   │   ├── user.py
│   │   ├── diary.py
│   │   ├── quote.py
│   │   ├── question.py
│   │   └── __init__.py
│   │
│   ├── services/
│   │   ├── auth_service.py
│   │   ├── diary_service.py
│   │   ├── quote_service.py
│   │   ├── question_service.py
│   │   └── __init__.py
│   │
│   ├── repositories/
│   │   ├── user_repo.py
│   │   ├── diary_repo.py
│   │   ├── quote_repo.py
│   │   ├── question_repo.py
│   │   ├── token_repo.py
│   │   └── __init__.py
│   │
│   ├── db/
│   │   ├── base.py
│   │   ├── session.py
│   │   ├── migrations/
│   │   └── __init__.py
│   │
│   ├── scraping/
│   │   ├── quote_scraper.py
│   │   ├── question_scraper.py
│   │   └── __init__.py
│   │
│   ├── main.py
│   └── __init__.py
│
├── tests/
│   ├── test_auth.py
│   ├── test_diary.py
│   ├── test_quote.py
│   └── test_question.py
│
├── .env
├── .env.dev
├── .gitignore
├── pyproject.toml
├── poetry.lock
└── README.md

명령어

실행

  • poetry run uvicorn app.main:app --reload

설치

    1. psycopg2-binary
    • PostgreSQL을 연결하기 위해서 필요
    1. poetry add email-validator
    • EmailStr 타입을 검증하기 위해서 email-validator 패키지가 필요
    1. poetry add pydantic-settings
    • FastAPI 앱 전체에서 하드코딩 없이, 환경 변수 기반 설정을 관리할 수 있게 도와주는 도구
    1. poetry add passlib[bcrypt]
    • 이렇게 하면 sh의 쉘 문법 때문에 passlib[bcrypt]를 “파일 패턴”으로 착각하고 오류 발생
      • poetry add 'passlib[bcrypt]' 따옴표로 감싸면 문제 해결

DB

.env 연결

1

  • postgres://[사용자이름]:[비밀번호]@[호스트주소]:[포트번호]/[데이터베이스이름]
    • ex. DATABASE_URL=postgres://postgres:1111@localhost:5432/fastapi_db

2

  • psql -h 000.000.00.000 -U hello_admin -d hellolist
DB_USER=hello_admin
DB_PASSWORD= (비밀번호를 여기 입력)
DB_HOST=000.000.00.000
DB_PORT=5432
DB_NAME=hellolist
DB_SCHEME=asyncpg

SECRET_KEY="mysecret"
ALGORITHM="HS256"
  • 서버 켜져있는지 확인하기 : ps aux | grep postgres

3

  • generate_schemas=True : True면 테이블을 모델에 있는 형태에 맞게 자동으로 DB에 생성

pydantic-settings

  • pydantic-settings을 이용하면 자동으로 .env 파일을 읽어서, 타입이 지정된 설정 객체로 만들어 줌
from app.core.config import settings

print(settings.DB_USER)
print(settings.SECRET_KEY)

DATABASE_URL = (
    f"asyncpg://{settings.DB_USER}:{settings.DB_PASSWORD}"
    f"@{settings.DB_HOST}:{settings.DB_PORT}/{settings.DB_NAME}"
)
  • 이 값들은 .env에 있는 내용이 자동으로 매핑
  • 타입(str, int, 등)도 자동으로 검증
    • .env 가 없을 때는 환경 변수(예: AWS, Docker 환경)에서도 자동으로 가져옴

원리 / 흐름

FastAPI 인증(Authorization) 흐름의 구조 이해

login → JWT 발급 → Authorization 헤더로 전달 → Depends(oauth2_scheme) 
				→ get_current_user → 보호된 API 실행
  • “요청이 들어올 때마다 Depends(oauth2_scheme)를 통해 토큰을 해석한다”
    • 즉,
        1. Authorization: Bearer <token>
        1. FastAPI가 토큰만 추출
        1. get_current_user() 에서 디코딩
        1. DB로 사용자 조회.

JWT의 동작 원리 (FastAPI + jose + passlib)

  • header: 암호화 알고리즘 정보 (HS256)
  • payload: 실제 데이터 (sub, exp, user_id)
  • signature: header + payload + SECRET_KEY 로 해시한 값
    • 즉, 서버는 JWT를 “저장”하지 않고 “검증만” 함
    • 로그아웃을 구현하려면 “서버가 기억해야 하므로” blacklist DB가 필요
profile
안녕하세요.

0개의 댓글