패스트캠퍼스 데브캠프 : 남궁성의 백엔드 개발 3기

FastAPI 기반 챗봇 프로젝트에서 로그인 인증 및 RDB 파트 구현기

Tech_JINI 2025. 4. 28. 10:24

이번 프로젝트에서는 FastAPI 기반의 챗봇 서비스에서 로그인 인증 처리RDB 연동을 맡아 구현하였다. 사용자 요청 흐름의 핵심이 되는 부분이었기 때문에, 명확한 데이터 흐름과 보안 설계가 중요했다.

 

⚙️ 왜 FastAPI를 선택했는가?

이 프로젝트에서는 FastAPI 프레임워크를 채택하였다. 여러 선택지가 있었지만, FastAPI를 사용한 이유는 다음과 같다:

  1. 비동기 처리 최적화
    FastAPI는 Python의 asyncio 기반으로 동작하여, I/O 처리에 강점을 가진다.
    챗봇처럼 빠르게 응답을 주고받아야 하는 서비스에서는 API 응답 속도가 매우 중요하다.
    비동기 요청과 DB 쿼리를 동시에 처리할 수 있어 병렬성 측면에서도 유리하다.
  2. Pydantic을 통한 데이터 검증
    요청/응답 스키마를 명확하게 정의할 수 있고, 자동으로 유효성 검사가 가능하다.
  3. Swagger UI 자동 생성
    FastAPI는 OpenAPI 스펙 기반의 문서를 자동 생성해주어, API 테스트와 협업이 용이하다.

 

🔐 FastAPI에서의 인증 방식 특징

FastAPI는 JWT, OAuth2, 세션 등 다양한 인증 방식을 유연하게 지원한다.
이번 프로젝트에서는 세션 기반 인증 방식을 선택하였다. 이 방식은 다음과 같은 FastAPI의 특성과 맞아떨어진다:

세션 저장 request.session["user_id"]와 같이 세션 데이터를 직접 저장할 수 있다
미들웨어 설정 Starlette 기반이므로 SessionMiddleware를 간단히 적용 가능
보안 JWT는 클라이언트에 정보가 담겨 있지만, 세션은 서버가 직접 관리하므로 민감한 데이터 보호에 유리

JWT보다 복잡한 설정 없이도 인증과 사용자 상태 유지를 할 수 있어, 개발 속도와 보안 모두를 고려해 세션 방식을 선택하게 되었다.

 

🔐 세션 기반 로그인 인증 처리

사용자가 채팅을 시작하기 전, 로그인 여부를 먼저 확인하는 구조로 설계하였다.
FastAPI에서는 세션 기반 인증 방식을 적용하였으며, 이는 다음과 같은 이유로 선택되었다:

  • 구현이 간단하고
  • 서버 측에서 세션을 직접 관리할 수 있어
  • 보안적인 통제에 유리하다는 장점이 있다.

로그인 요청(/login)이 들어오면, 이메일과 비밀번호를 검증한 뒤 다음과 같은 방식으로 세션에 사용자 정보를 저장한다.

request.session["user_id"] = user.user_id

 

이후 주문 정보, 환불 내역 등 민감한 정보 조회 API에서는 이 user_id를 기준으로 데이터에 접근할 수 있도록 하였다.

🔍 참고로 Swagger를 통해 API 테스트를 진행하며 세션 저장 및 필터링 로직의 정확성을 검증하였다.


 

🧩 LLM 분류 결과에 따른 RDB 쿼리 처리

챗봇에서 LLM이 사용자의 질문을 이해하고, 그에 맞는 의도를 분류하면
나는 해당 의도에 맞춰 MySQL 데이터베이스에서 데이터를 조회하거나 수정하는 쿼리를 작성하였다.
비동기 쿼리 처리를 위해 databases + aiomysql 조합을 사용하였다.

query = "SELECT * FROM orders WHERE user_id = :user_id ORDER BY created_at DESC"
rows = await database.fetch_all(query=query, values={"user_id": user_id})

 

🔄 비동기 쿼리 처리 방식을 선택한 이유

기존의 pymysql, mysql-connector 등은 동기 방식이라, 하나의 쿼리를 처리할 때까지 다음 처리를 기다려야 한다.
하지만 챗봇 서비스에서는 다수의 사용자 요청이 짧은 시간에 몰릴 수 있기 때문에, DB 처리 병목을 줄이기 위해 비동기 처리 방식을 택했다.

이에 따라 다음 조합을 사용했다:

  • databases 패키지: SQLAlchemy 없이도 간편하게 비동기 SQL 처리 가능
  • aiomysql: MySQL과 호환되는 비동기 드라이버

 

📊 내가 처리한 주요 기능 (의도 → 테이블)

아래는 LLM이 분류한 의도와 내가 연동한 테이블, 처리 로직을 정리한 표이다:

사용자 의도연동 테이블처리 내용
주문 목록 조회 Orders, OrderItems 세션 user_id 기준 주문 목록 필터링
주문 상세 조회 Orders, OrderItems order_code → order_id 변환 후 상세 조회
환불 요청 Refunds, Orders order_code로 환불 처리 요청
환불 내역 조회 Refunds, Orders user_id 기준 환불 정보 필터링
상품 재고 조회 ProductStock product_id에 해당하는 재고 수량 조회
상품 정보 조회 Products, ProductDetail LLM 응답용 상품 정보 응답
매장 정보 조회 StoreInfo 매장 이름, 위치, 운영 시간 반환
배송 상태 조회 Delivery order_id에 해당하는 배송 상태 응답

 

🧠 느낀 점

처음에는 RDB 연동이나 인증 방식 구현이 단순히 “쿼리를 작성하고 응답하면 된다”고 생각했지만,
실제로는 사용자 흐름에 맞게 데이터를 어떻게 안전하게 가져올 것인지,
LLM과의 연결성을 고려해 응답 형태를 어떻게 구성할 것인지가 더 중요한 포인트였다.

이번 작업을 통해 FastAPI에서의 인증 방식과 비동기 쿼리 처리 방식에 대해 깊이 이해할 수 있었고,
실제 서비스를 염두에 두고 백엔드 구조를 설계하는 경험을 쌓을 수 있었다.