1. 라우팅 설정
1.1 자동 라우트 생성
Django REST Framework에서 뷰셋(ViewSet)을 사용할 경우, 라우터를 통해 자동으로 URL 패턴을 생성할 수 있습니다. 기본적인 사용법은 다음과 같습니다.
from rest_framework.routers import SimpleRouter
# 라우터 인스턴스 생성
router = SimpleRouter()
# 라우트 등록: prefix, 뷰셋, 이름
router.register('user', views.UserView, 'user')
# URL 패턴에 추가 (두 가지 방식 중 선택)
# 방법 1
urlpatterns += router.urls
# 방법 2
urlpatterns = [
path('', include(router.urls)),
]
1.2 @action 데코레이터 활용
뷰셋 내에서 표준 CRUD 외의 커스텀 메서드를 정의할 때는 @action 데코레이터로 URL 매핑을 설정합니다.
from rest_framework.decorators import action
class UserView(ViewSet):
# methods: 허용할 HTTP 메서드 목록
# detail: False면 /user/login/, True면 /user/{pk}/login/ 형태
# url_path: URL 경로 커스터마이징 (기본값: 메서드명)
# url_name: 역참조용 별칭
@action(methods=['POST'], detail=False, url_path='login')
def login(self, request):
# 로그인 로직
pass
2. 로그인 API 구현
모델 정의
from django.db import models
class User(models.Model):
name = models.CharField(max_length=32)
password = models.CharField(max_length=32)
def __str__(self):
return self.name
class UserToken(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
token = models.CharField(max_length=32, null=True)
뷰 작성
import uuid
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet
class UserView(ViewSet):
@action(methods=['POST'], detail=False, url_path='login')
def login(self, request):
username = request.data.get('name')
password = request.data.get('password')
user = User.objects.filter(name=username, password=password).first()
if user:
token = str(uuid.uuid4())
UserToken.objects.update_or_create(
defaults={'token': token},
user=user
)
return Response({
'status': 200,
'message': '인증 성공',
'token': token
})
else:
return Response({
'status': 401,
'message': '인증 실패'
})
URL 설정
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('user', views.UserView, 'user')
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
3. 인증(Authentication) 처리
커스텀 인증 클래스를 만들어 요청이 인증된 사용자로부터 왔는지 검증합니다. 토큰 값을 기반으로 DB에서 일치하는 레코드를 찾고, 결과에 따라 사용자 정보를 반환하거나 인증 예외를 발생시킵니다.
from rest_framework.authentication import BaseAuthentication
from rest_framework.exceptions import AuthenticationFailed
class TokenAuthentication(BaseAuthentication):
def authenticate(self, request):
# 쿼리 파라미터에서 토큰 추출
token = request.GET.get('token')
# 토큰으로 DB 조회
token_record = UserToken.objects.filter(token=token).first()
if token_record:
# 인증 성공: (사용자 객체, 토큰) 반환
return (token_record.user, token)
else:
# 인증 실패
raise AuthenticationFailed('인증되지 않은 사용자입니다.')