본문으로 건너뛰기
백엔드 기초집: Python FastAPILESSON 23

권한 처리와 보안 기초

난이도초급
예상 시간35분
선수지식이전 강의

23강. 권한 처리와 보안 기초

1. 이번 강의에서 해결할 문제

로그인만 확인하면 사용자가 다른 사람의 기록도 수정하거나 삭제할 수 있습니다. 인증된 신원에 소유권과 역할 정책을 추가합니다.

2. 학습 목표

3. 핵심 개념

인증은 누구인지 확인하고 인가는 그 사용자가 행동할 수 있는지 판단합니다. 일반 사용자는 자신의 기록만 바꾸고 관리자는 운영 정책에 따라 모든 기록을 관리할 수 있게 합니다. 요청 body의 user_id를 신뢰하지 않고 JWT에서 복원한 사용자 id를 사용해야 수평 권한 상승을 막을 수 있습니다.

4. 단계별 코드 예시

파일 경로: game-ranking-api/app/dependencies.py에 추가

app/dependencies.py
CurrentUser = Annotated[User, Depends(get_current_user)]


def require_admin(current_user: CurrentUser) -> User:
if current_user.role != "admin":
raise HTTPException(status_code=403, detail="관리자 권한이 필요합니다")
return current_user


AdminUser = Annotated[User, Depends(require_admin)]

파일 경로: game-ranking-api/app/routers/records.py

app/routers/records.py
@router.post("", response_model=RecordRead, status_code=201)
def create_record(payload: RecordCreate, db: DbSession, current_user: CurrentUser) -> GameRecord:
record = GameRecord(user_id=current_user.id, **payload.model_dump())
db.add(record)
db.commit()
db.refresh(record)
return record


@router.delete("/{record_id}", status_code=204)
def delete_record(record_id: int, db: DbSession, current_user: CurrentUser) -> Response:
record = db.get(GameRecord, record_id)
if record is None:
raise HTTPException(status_code=404, detail="기록을 찾을 수 없습니다")
if record.user_id != current_user.id and current_user.role != "admin":
raise HTTPException(status_code=403, detail="이 기록을 삭제할 권한이 없습니다")
db.delete(record)
db.commit()
return Response(status_code=204)

파일 경로: game-ranking-api/app/routers/admin.py

app/routers/admin.py
from fastapi import APIRouter

router = APIRouter(prefix="/admin", tags=["admin"])


@router.get("/stats")
def admin_stats(db: DbSession, admin: AdminUser) -> dict[str, int]:
return {"users": db.scalar(select(func.count()).select_from(User)) or 0}

실행 위치: game-ranking-api/

python -m uvicorn app.main:app --reload
Invoke-WebRequest -Method Delete http://127.0.0.1:8000/records/2 -Headers @{Authorization="Bearer $token"} -SkipHttpErrorCheck
Invoke-WebRequest http://127.0.0.1:8000/admin/stats -Headers @{Authorization="Bearer $token"} -SkipHttpErrorCheck

5. 코드가 동작하는 이유

생성 시 user_id를 body가 아니라 current_user에서 가져오므로 다른 소유자를 가장할 수 없습니다. 삭제는 존재 여부 다음에 소유자 또는 관리자 조건을 검사합니다. require_admin은 여러 관리자 endpoint에서 동일 정책을 재사용합니다.

6. 자주 하는 실수와 해결법

7. 직접 실습

8. 이해 점검 질문 3개

9. 핵심 요약

MINI QUIZ

권한 처리와 보안 기초 미니 퀴즈

선택 즉시 정답과 해설을 확인할 수 있습니다. 결과는 이 브라우저에만 저장됩니다.

0 / 2
  1. 문제 1“권한 처리와 보안 기초” 작업 전 검토에서 채택해야 할 안전 기준은 무엇인가요?
  2. 문제 2“권한 처리와 보안 기초”의 작업 기준으로 ‘오류 로그에 Authorization header를 남깁니다.’을 진단하거나 바로잡은 선택은 무엇인가요?
LESSON STATUS

학습을 마쳤나요?

직접 실습과 점검 질문까지 확인한 뒤 완료로 표시하세요.

23강. 권한 처리와 보안 기초 미완료 상태