FastAPI 서버개발, 패스워드 해싱

현대 웹 애플리케이션에서 사용자 인증 및 보안을 확보하는 것은 매우 중요한 문제입니다. 특히, 비밀번호와 같은 민감한 정보는 적절하게 보호되어야 합니다. 이를 위해 우리는 FastAPI를 사용하여 백엔드 서버를 개발하고, 비밀번호 해싱을 통해 사용자 비밀번호를 안전하게 저장하는 방법을 알아보겠습니다.

1. FastAPI 소개

FastAPI는 Python으로 작성된 현대적인 웹 프레임워크로, 비동기 프로그래밍을 지원하고, OpenAPI 및 JSON Schema를 자동으로 생성할 수 있습니다. 성능이 뛰어나며, 신속한 프로토타이핑과 설계 검증에 적합합니다. FastAPI는 RESTful API 개발을 위한 매우 직관적이고 간편한 접근 방식을 제공합니다.

2. 패스워드 해싱이란?

패스워드 해싱은 사용자가 입력한 비밀번호를 해시 함수를 통해 변형해 저장하는 작업입니다. 이를 통해 비밀번호가 노출되더라도 원래 비밀번호를 알아낼 수 없도록 방지할 수 있습니다. 해싱 알고리즘으로는 BCrypt, Argon2, PBKDF2 등이 있으며, 이들 각각은 복잡성과 보안 수준이 다릅니다.

2.1 해싱 알고리즘

비밀번호 해싱에서 가장 널리 사용되는 알고리즘은 다음과 같습니다:

  • BCrypt: 비밀번호를 해싱할 때 적절한 비용 인자를 사용하여 보안을 강화하는 알고리즘입니다.
  • Argon2: 2015년 패스워드 해싱 대회에서 우승한 알고리즘으로, 메모리 요구 사항을 증가시켜 공격에 대한 저항력을 높입니다.
  • PBKDF2: 반복적 해싱을 통해 비밀번호의 복잡성을 높이는 알고리즘으로, 일정량의 시간과 메모리를 소모하도록 설계되었습니다.

3. FastAPI 환경 구축

이제 FastAPI 프로젝트를 설정하고 비밀번호를 안전하게 해싱하기 위한 준비를 해보겠습니다.

3.1 FastAPI 설치

FastAPI 및 해싱을 위한 필요한 라이브러리를 설치합니다. 다음 명령어를 실행하여 필요한 패키지를 설치합니다:

pip install fastapi uvicorn passlib[bcrypt]

3.2 프로젝트 구조

다음과 같은 디렉토리 구조를 생성합니다:


project/
│
├── app/
│   ├── __init__.py
│   ├── main.py
│   └── models.py
└── requirements.txt
    

3.3 기본 FastAPI 앱 작성

이제 FastAPI 애플리케이션을 작성해보겠습니다. main.py 파일에 기본 API를 설정합니다.


from fastapi import FastAPI
from pydantic import BaseModel
from passlib.context import CryptContext

app = FastAPI()
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")

# 사용자 모델 정의
class User(BaseModel):
    username: str
    password: str

# 비밀번호 해싱 함수
def hash_password(password: str) -> str:
    return pwd_context.hash(password)

# 사용자 등록 엔드포인트
@app.post("/register/")
async def register(user: User):
    hashed_password = hash_password(user.password)
    return {"username": user.username, "hashed_password": hashed_password}
    

4. 비밀번호 해싱 구현

위 코드에서는 비밀번호 해싱을 위한 간단한 FastAPI 애플리케이션을 작성하였습니다. 이 애플리케이션은 사용자가 등록할 때 비밀번호를 해싱하여 반환합니다.

4.1 비밀번호 해싱 과정 설명

  • 사용자가 등록하면, register 엔드포인트가 호출됩니다.
  • 입력받은 비밀번호는 hash_password 함수를 통해 해싱됩니다.
  • 해싱된 비밀번호는 JSON 응답으로 반환됩니다.

5. 서버 실행하기

FastAPI 서버를 실행하기 위해 터미널에서 다음 명령어를 입력합니다:

uvicorn app.main:app --reload

서버가 성공적으로 실행되면, http://127.0.0.1:8000/docs를 방문하여 Swagger UI에서 API를 테스트할 수 있습니다.

6. 비밀번호 검증

사용자가 로그인하면, 입력한 비밀번호와 DB에 저장된 해싱된 비밀번호를 비교해야 합니다. 이를 위해 비밀번호 검증 함수를 추가해 보겠습니다.


# 비밀번호 검증 함수
def verify_password(plain_password: str, hashed_password: str) -> bool:
    return pwd_context.verify(plain_password, hashed_password)

@app.post("/login/")
async def login(user: User):
    # 비밀번호 검증 로직 (여기서는 간단히 하드코딩)
    stored_hashed_password = "$2b$12$KixR7Pq2B7lZq5NOsx.xreOS5Jz4P3qv1E8pF8ozFpXZKLaMvvWry"  # 예시 해시
    if verify_password(user.password, stored_hashed_password):
        return {"message": f"Welcome {user.username}"}
    else:
        return {"message": "Invalid credentials"}
    

7. 결론

이번 글에서는 FastAPI로 간단한 백엔드 서버를 구성하고 패스워드 해싱 기능을 추가하는 방법을 배웠습니다. 비밀번호는 해싱을 통해 저장함으로써 사용자의 정보를 안전하게 보호할 수 있습니다. 본 예제는 간단한 형태이므로, 실제 서비스에서는 데이터베이스와의 연동, 에러 처리, 유효성 검증 등 추가적인 로직이 필요합니다.

8. 추가 자료

FastAPI 및 패스워드 해싱 관련 추가 자료를 아래와 같이 추천합니다:

FastAPI를 통해 성능 좋고 안전한 웹 API를 구축해 보세요!

© 2023 FastAPI 개발 강좌. All rights reserved.