Post
[Python 5/6] To-do CRUD API 구현: 본인 데이터 권한 체크
[Python 5/6] To-do CRUD API 구현: 본인 데이터 권한 체크
1) 라우터 작성
app/routers/todos.py
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db import get_db
from app.deps import get_current_user
from app.models import Todo, User
from app.schemas import TodoCreate, TodoOut, TodoUpdate
router = APIRouter(prefix='/todos', tags=['todos'])
@router.get('', response_model=list[TodoOut])
def list_todos(current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
return db.query(Todo).filter(Todo.owner_id == current_user.id).order_by(Todo.id.desc()).all()
@router.post('', response_model=TodoOut)
def create_todo(payload: TodoCreate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
todo = Todo(title=payload.title, owner_id=current_user.id)
db.add(todo)
db.commit()
db.refresh(todo)
return todo
@router.patch('/{todo_id}', response_model=TodoOut)
def update_todo(todo_id: int, payload: TodoUpdate, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
todo = db.query(Todo).filter(Todo.id == todo_id, Todo.owner_id == current_user.id).first()
if not todo:
raise HTTPException(status_code=404, detail='할 일을 찾을 수 없습니다.')
if payload.title is not None:
todo.title = payload.title
if payload.done is not None:
todo.done = payload.done
db.commit()
db.refresh(todo)
return todo
@router.delete('/{todo_id}', status_code=204)
def delete_todo(todo_id: int, current_user: User = Depends(get_current_user), db: Session = Depends(get_db)):
todo = db.query(Todo).filter(Todo.id == todo_id, Todo.owner_id == current_user.id).first()
if not todo:
raise HTTPException(status_code=404, detail='할 일을 찾을 수 없습니다.')
db.delete(todo)
db.commit()
2) main.py 등록
app/main.py
from fastapi import FastAPI
from app.db import Base, engine
from app.routers.health import router as health_router
from app.routers.auth import router as auth_router
from app.routers.todos import router as todos_router
Base.metadata.create_all(bind=engine)
app = FastAPI(title='Todo Backend')
app.include_router(health_router)
app.include_router(auth_router)
app.include_router(todos_router)
3) 수동 테스트 순서
/auth/register/auth/login→ access_token 확보/todosPOST/GET/PATCH/DELETE 호출 (Authorization: Bearer …)
핵심 포인트
- SQL 쿼리에서
owner_id == current_user.id를 항상 조건으로 넣는다. - 이 한 줄이 빠지면 다중 사용자 데이터 누출 사고가 발생한다.
댓글