
권한 처리 (자기 글만 수정 가능)
from fastapi import APIRouter, Depends, HTTPException
from app.models.diary import Diary
from app.core.dependencies import get_current_user
from app.models.user import User
router = APIRouter(prefix="/diary", tags=["Diary"])
@router.put("/{diary_id}")
async def update_diary(
diary_id: int,
title: str,
content: str,
current_user: User = Depends(get_current_user)
):
diary = await Diary.get_or_none(id=diary_id)
if not diary:
raise HTTPException(status_code=404, detail="Diary not found")
if diary.user_id != current_user.id:
raise HTTPException(status_code=403, detail="You are not the author of this diary")
diary.title = title
diary.content = content
await diary.save()
return {"message": "Diary updated successfully", "diary": diary}
권한처리(자기글만 삭제가능)
async def update_diary(
diary_id: int,
title: str,
content: str,
current_user: User = Depends(get_current_user)
):
@router.delete("/{diary_id}")
async def delete_diary(
diary_id: int,
current_user: User = Depends(get_current_user)
):
diary = await Diary.get_or_none(id=diary_id)
if not diary:
raise HTTPException(status_code=404, detail="Diary not found")
if diary.user_id != current_user.id:
raise HTTPException(status_code=403, detail="You are not the author of this diary")
await diary.delete()
return {"message": "Diary deleted successfully"}
- 비동기 뷰 함수 정의
- diary_id: int:
- 경로 파라미터(path param). URL의 {diary_id}를 정수로 받음.
- title: str, content: str:
- 쿼리 스트링 또는 폼/바디로 들어올 수 있는 함수 파라미터.
- current_user: User = Depends(get_current_user):
- 요청 헤더의 Bearer 토큰을 읽어 get_current_user가 현재 로그인한 유저를 찾아서 주입.
- 인증 실패/만료/블랙리스트면 여기서 예외 발생.
diary = await Diary.get_or_none(id=diary_id)

핵심
- current_user: User = Depends(get_current_user)
- 이 엔드포인트를 실행하기 전에, get_current_user() 함수를 먼저 실행해서
- 로그인한 사용자를 찾아내고, 그 결과(User 객체)를 current_user 변수에 자동으로 넣어달라
Depends()
- 의존성 주입(Dependency Injection) 기능
- 공통적으로 필요한 로직을 함수 바깥에서 자동으로 실행하게 해주는 FastAPI의 도우미
get_current_user()
from fastapi import Depends, HTTPException
from jose import jwt, JWTError
from app.core.config import settings
from app.repositories.user_repo import UserRepository
from app.repositories.token_repo import TokenRepository
from fastapi.security import OAuth2PasswordBearer
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/auth/login")
async def get_current_user(token: str = Depends(oauth2_scheme)):
if await TokenRepository.is_blacklisted(token):
raise HTTPException(status_code=401, detail="Token has been revoked")
try:
payload = jwt.decode(token, settings.SECRET_KEY, algorithms=[settings.ALGORITHM])
username: str = payload.get("sub")
if username is None:
raise HTTPException(status_code=401, detail="Invalid token")
except JWTError:
raise HTTPException(status_code=401, detail="Invalid token")
user = await UserRepository.get_by_username(username)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
| 단계 | 설명 | 실패 시 |
|---|
| ① | 요청 헤더의 Authorization: Bearer <token> 에서 토큰 꺼냄 (oauth2_scheme) | 자동 401 |
| ② | DB에서 블랙리스트 여부 확인 (로그아웃된 토큰 차단) | 401 |
| ③ | JWT 토큰 복호화 → payload 추출 | 401 |
| ④ | sub(username) 가져와서 검증 | 401 |
| ⑤ | DB에서 해당 username 유저 조회 | 404 |
| ✅ | 성공 시 User 객체 반환 | - |