본문 바로가기
프로그램 (PHP,Python)

FastAPI에서 Swagger UI 보호조치를 위한 URL 변경 및 사용자 인증

by 날으는물고기 2024. 1. 13.

FastAPI에서 Swagger UI 보호조치를 위한 URL 변경 및 사용자 인증

FastAPI는 기본적으로 Swagger UI를 사용하여 API 문서를 생성하며, 이 문서는 /docs 엔드포인트에서 제공됩니다. 만약 /docs 대신 다른 URL로 Swagger UI를 노출하고 싶다면 FastAPI의 설정을 조정하여 이를 변경할 수 있습니다.

 

다음은 FastAPI에서 Swagger UI의 URL을 변경하는 방법입니다.

from fastapi import FastAPI
from fastapi.openapi.models import APIKey
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
from fastapi.openapi.models import OAuthFlowAuthorizationCode
from fastapi.openapi.models import OAuthFlowImplicit
from fastapi.openapi.models import OAuthFlows
from fastapi.openapi.models import OAuthFlowPassword
from fastapi.openapi.models import OAuthFlowRefreshToken
from fastapi.openapi.models import OAuthFlows as OAuthFlowsModel
from fastapi.openapi.models import OAuthFlowAuthorizationCode
from fastapi.openapi.models import OAuthFlowImplicit
from fastapi.openapi.models import OAuthFlowPassword
from fastapi.openapi.models import OAuthFlowRefreshToken
from fastapi.openapi.models import OAuthFlows

app = FastAPI()

# 기본적으로 /docs 에서 Swagger UI를 제공합니다.
# 여기서 /custom-docs로 변경해보겠습니다.
app.docs_url = "/custom-docs"

# 또한, ReDoc의 URL도 변경할 수 있습니다.
# 기본값은 /redoc 입니다.
app.redoc_url = "/custom-redoc"

# 서버 실행
if __name__ == "__main__":
    import uvicorn

    uvicorn.run(app, host="127.0.0.1", port=8000)

위 코드에서 app.docs_urlapp.redoc_url 속성을 사용하여 Swagger UI와 ReDoc의 URL을 변경할 수 있습니다. 위의 예제에서는 /custom-docs/custom-redoc로 변경되었습니다.

 

이렇게 설정을 변경하면 FastAPI 애플리케이션을 실행할 때 새로운 URL로 Swagger UI와 ReDoc이 노출됩니다. 변경된 URL로 이동하여 API 문서를 확인할 수 있습니다.

 

FastAPI에서 Swagger UI에 HTTP 기본 인증(Authorize)을 적용하려면 Security 객체를 사용하여 해당 설정을 구성해야 합니다. 이를 통해 API에 대한 요청을 보낼 때 기본적으로 사용자 이름과 비밀번호를 입력해야 합니다.

 

아래는 HTTP 기본 인증을 Swagger UI에 적용하는 간단한 FastAPI 예제입니다. 이 예제에서는 Depends를 사용하여 간단한 사용자 검증 함수를 구현합니다.

from fastapi import FastAPI, Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials

app = FastAPI()

# HTTP 기본 인증을 사용하는 Security 객체를 생성합니다.
security = HTTPBasic()

# 사용자 검증 함수
def verify_user(credentials: HTTPBasicCredentials = Depends(security)):
    # 실제로는 여기에서 사용자의 인증을 확인하는 로직을 구현해야 합니다.
    # 예제에서는 사용자 이름이 "user"이고 비밀번호가 "password"인 경우에만 허용합니다.
    correct_username = "user"
    correct_password = "password"

    if credentials.username == correct_username and credentials.password == correct_password:
        return credentials.username

    # 인증에 실패하면 HTTP 401 Unauthorized 예외를 발생시킵니다.
    raise HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Invalid credentials",
        headers={"WWW-Authenticate": "Basic"},
    )

# API 경로에 사용자 검증 함수를 의존성으로 추가합니다.
@app.get("/secure-endpoint")
def secure_endpoint(username: str = Depends(verify_user)):
    return {"message": f"Hello, {username}!"}

이제 Swagger UI에 Authorize 버튼이 나타날 것입니다. Authorize 버튼을 클릭하면 사용자 이름과 비밀번호를 입력하는 모달이 표시됩니다. 여기서 예제의 경우 "user" 및 "password"를 입력하면 Swagger UI에서 보호된 엔드포인트에 대한 요청을 보낼 수 있습니다.

 

이는 단순한 예제이며, 실제 프로덕션에서는 사용자 검증을 더 강화하고 안전한 방법으로 수행해야 합니다. 실제로는 데이터베이스와 연결하여 사용자를 확인하는 방법 등을 고려해야 합니다.

 

FastAPI를 사용하여 데이터베이스를 다루는 간단한 예제를 통해, 데이터베이스를 통한 GET 및 POST 요청을 어떻게 처리하는지에 대해 설명하겠습니다. 이 예제에서는 SQLite를 사용하겠습니다.

 

먼저, FastAPI 애플리케이션을 작성하고 데이터베이스 모델을 정의합니다.

from fastapi import FastAPI, HTTPException
from fastapi import Depends, HTTPException, status
from fastapi.security import OAuth2PasswordBearer
from sqlalchemy import create_engine, Column, Integer, String, Sequence, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Session
from sqlalchemy.orm import relationship

# SQLite 메모리 DB를 사용합니다.
DATABASE_URL = "sqlite:///:memory:"

# SQLAlchemy 엔진 및 세션을 생성합니다.
engine = create_engine(DATABASE_URL)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# SQLAlchemy 모델을 정의합니다.
Base = declarative_base()

class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, Sequence("item_id_seq"), primary_key=True, index=True)
    name = Column(String, index=True)
    description = Column(String)
    owner_id = Column(Integer, ForeignKey("users.id"))

class User(Base):
    __tablename__ = "users"
    id = Column(Integer, Sequence("user_id_seq"), primary_key=True, index=True)
    username = Column(String, index=True)
    email = Column(String, index=True)
    hashed_password = Column(String)

# 모델을 데이터베이스에 생성합니다.
Base.metadata.create_all(bind=engine)

app = FastAPI()

이제 데이터베이스를 사용하여 GET 및 POST 요청을 처리하는 API 경로를 추가하겠습니다.

from typing import List

# 의존성 함수를 사용하여 세션을 가져옵니다.
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

# GET: 모든 아이템 조회
@app.get("/items/", response_model=List[Item])
def read_items(skip: int = 0, limit: int = 10, db: Session = Depends(get_db)):
    items = db.query(Item).offset(skip).limit(limit).all()
    return items

# GET: 특정 아이템 조회
@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int, db: Session = Depends(get_db)):
    item = db.query(Item).filter(Item.id == item_id).first()
    if item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

# POST: 아이템 생성
@app.post("/items/", response_model=Item)
def create_item(item: Item, db: Session = Depends(get_db)):
    db.add(item)
    db.commit()
    db.refresh(item)
    return item

위의 코드에서는 /items/ 엔드포인트를 통해 모든 아이템을 조회하거나, 특정 아이템을 조회하고, 새로운 아이템을 생성할 수 있습니다. 이를 통해 Swagger UI에서는 각 API 엔드포인트에 대한 입력과 출력을 확인할 수 있습니다.

 

FastAPI는 자동으로 Swagger 문서를 생성하므로, 위의 코드를 실행한 후 http://127.0.0.1:8000/docs로 이동하여 Swagger UI를 열 수 있습니다. Swagger UI에서는 각 엔드포인트에 대한 상세한 설명과 함께 테스트할 수 있는 폼이 표시됩니다.

 

입력 폼에서 데이터를 입력하고 "Execute" 버튼을 클릭하여 API를 호출할 수 있습니다. 결과는 Swagger UI에서 확인할 수 있으며, FastAPI 애플리케이션의 로그에서도 확인할 수 있습니다.

728x90

댓글