FastAPI에서 CSRF(Cross-Site Request Forgery) 적용하는 방법
1. 자체적으로 CSRF 보호 구현하기
- FastAPI에서는 기본적으로 CSRF를 제공하지 않기 때문에, 이를 구현하려면 요청의 유효성을 직접 체크해야 한다.
- CSRF 보호를 구현하는 일반적인 방법:
- CSRF Token 생성: 사용자가 로그인하거나 세션을 시작할 때 CSRF 토큰을 생성한다.
- 이 토큰은 세션 쿠키나 HTTP 헤더를 통해 클라이언트에게 전달된다.
- CSRF Token 검증: 클라이언트가 서버에 요청을 보낼 때 CSRF 토큰을 포함시켜야 하며, 서버는 해당 토큰이 유효한지 검증한다.
- 이 검증은 보통 요청의 Authorization 헤더나 X-CSRF-Token과 같은 커스텀 헤더에 토큰을 포함시키는 방식으로 처리된다.
1) 자체 구현 예시:
- CSRF 토큰 생성:
- 서버는 사용자가 로그인할 때 세션에 CSRF 토큰을 저장한다.
- 이 토큰을 HTML 페이지나 API 응답에서 클라이언트에게 전달한다.
- CSRF 토큰 검증:
- 클라이언트는 POST 요청을 보낼 때 해당 토큰을 X-CSRF-Token 헤더에 포함시킵니다.
- 서버는 이 토큰을 요청 헤더에서 가져와 세션에 저장된 토큰과 비교합니다.
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse
import secrets
app = FastAPI()
# CSRF 토큰을 세션에 저장하는 임시 방법
csrf_tokens = {}
@app.get("/", response_class=HTMLResponse)
async def get_form(request: Request):
# CSRF 토큰 생성
csrf_token = secrets.token_hex(32)
csrf_tokens[csrf_token] = True # 세션에 토큰 저장 (임시 방식)
# HTML 폼에 CSRF 토큰 포함
return f"""
<form method="POST" action="/submit">
<input type="hidden" name="csrf_token" value="{csrf_token}">
<input type="text" name="username">
<input type="submit">
</form>
"""
@app.post("/submit")
async def submit_form(request: Request):
form = await request.form()
csrf_token = form.get("csrf_token")
# CSRF 토큰 검증
if not csrf_tokens.get(csrf_token):
raise HTTPException(status_code=400, detail="Invalid CSRF token")
# 요청 처리 (예: 사용자 이름 저장)
username = form.get("username")
return {"message": f"Hello, {username}!"}
2. CSRF 보호를 위한 라이브러리 사용
- FastAPI에서 CSRF 보호를 손쉽게 적용하려면 외부 라이브러리를 사용하는 방법이 더 효율적이다.
- 대표적으로 사용할 수 있는 라이브러리는 starlette_csrf와 같은 CSRF 보호 라이브러리이다.
- starlette_csrf: starlette_csrf는 Starlette 기반의 CSRF 보호 미들웨어로, FastAPI에서도 사용할 수 있다. 이 라이브러리는 CSRF 토큰을 자동으로 생성하고, 요청에서 이를 검증해준다.
1) 설치
pip install starlette_csrf
2) 미들웨어로 추가
from fastapi import FastAPI, Depends
from starlette.middleware.csrf import CSRFMiddleware
app = FastAPI()
# CSRF 미들웨어 추가
app.add_middleware(CSRFMiddleware, secret="your-secret-key")
@app.post("/submit")
async def submit_form(csrf_token: str = Depends(CSRFMiddleware.csrf_token)):
# CSRF 토큰 검증을 자동으로 처리
return {"message": "CSRF token is valid"}
'Study > fastapi' 카테고리의 다른 글
fastapi + sqlalchemy + ORM을 이용한 페이지네이션 방법들 (0) | 2025.01.14 |
---|---|
FastAPI의 예외 처리, blinker, SQLAlchemy의 listens_for 정리 (0) | 2025.01.14 |
[udemy] FastAPI - The Complete Course 2025 (Beginner + Advanced) - 학습 후기 (0) | 2025.01.14 |
[udemy] FastAPI - The Complete Course 2025 (Beginner + Advanced) - 학습 정리 3 (0) | 2025.01.14 |
[udemy] FastAPI - The Complete Course 2025 (Beginner + Advanced) - 학습 정리 2 (0) | 2025.01.10 |
댓글