Django REST Framework 라우팅, 로그인 API 및 인증 처리

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('인증되지 않은 사용자입니다.')

태그: Django REST Framework 라우팅 SimpleRouter action 데코레이터 ViewSet

6월 25일 18:18에 게시됨