AWS Cognito + DRF 로그인 구현하기(with React)(3)

Jongwho Park·2021년 5월 14일
0

CognitoWithDRF

목록 보기
3/3

User 모델

from django.db import models
from django.contrib.auth.base_user import AbstractBaseUser
from django.contrib.auth.models import PermissionsMixin
from django.contrib.auth.validators import UnicodeUsernameValidator
from django.contrib.auth.signals import user_logged_in
from django.dispatch import receiver

# 이전 포스트에서 만들었던 커스텀 유저 모델
from cognito_auth.models import AbstarctBaseUserModel

class User(PermissionsMixin, AbstarctBaseUserModel, AbstractBaseUser):
    username_validator = UnicodeUsernameValidator()

    username = models.CharField('Username', max_length=255, unique=True, validators=[username_validator])
    is_active = models.BooleanField('Active', default=True)
    email = models.EmailField('Email address', blank=True)
    is_staff = models.BooleanField(
        'staff status',
        default=False,
        help_text='Admin using'
    )
    USERNAME_FIELD = 'username'
    EMAIL_FIELD = 'email'
    REQUIRED_FIELDS = ['email']

    @property
    def is_django_user(self):
        return self.has_usable_password()

이전 게시물에서 만들었던 AbstractUser를 import 하여 Usermodel을 작성합니다.

Serializer

이제 모든 설정이 끝났으니, Serializer를 생성하여 Views를 통해 받을 준비를 해봅시다.

from rest_framework import serializers
from app_account.models import User


class UserSerializer(serializers.ModelSerializer):

    class Meta:
        model = User
        fields = '__all__'

만들었던 User 모델을 사용하여 Serializer를 작성합니다.

Views.py

from rest_framework.generics import GenericAPIView
from rest_framework.mixins import RetrieveModelMixin
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated

from app_account.api.serializers import UserSerializer

class UserProfileApiView(RetrieveModelMixin, GenericAPIView):
    serializer_class = UserSerializer
    permission_classes = (IsAuthenticated, )

    def get_object(self):
        return self.request.user

    def get(self, request, *args, **kwargs):
        return self.retrieve(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return Response(self.serializer_class.data)

Urls.py

from django.contrib import admin
from django.urls import path
from app_account.views import UserProfileApiView

urlpatterns = [
    path('api/v1/me', UserProfileApiView.as_view(), name='login')
]

간단한 예제 구현을 위해 생성한 프로젝트 아래 urls.py에서 바로 View로 연결할 수 있도록 설정했습니다.(원래 각 앱 아래에 urls.py를 생성하고, 프로젝트에서 각 앱의 urls.py를 연결해야 합니다.)

React에서 Flow

React에서는 aws-amplify를 이용하여 로그인, 비밀번호 찾기 등 Cognito와 관련된 모든 기능을 구현할 수 있습니다.
https://docs.amplify.aws/lib/auth/getting-started/q/platform/js#authentication-with-amplify

React에서 로그인 후 Flow 요약

React에서 로그인 시 Access Token을 발행합니다. 이 Access Token에는 유저의 정보(Cognito의 sub-id 등등)를 포함하고 있습니다. 이 Access Token이 어떻게 로그인, 유저 정보 저장에 사용되는지 설명드리겠습니다.
1. Django 시스템에 유저 정보가 headers에 담겨 들어오면, Settings.py에서 설정한, DEFAULT_AUTHENTICATION_CLASSES의 함수를 실행하여 인증을 하게됩니다.
2. Settings.py에서 설정한 JWT_AUTH 설정 값에서 DECODE_HANDLER와 GET_USERNAME_HANDER의 함수를 실행합니다.
3. jwt_decoder를 우선 실행하여 받은 Access Token을 Decode 합니다. 이 jwt_decoder에서 cognito에서 받은 토큰을 Decode하여 토큰에서 받은 정보들을 Cognito 서버에 확인합니다.
4. Cognito에서 확인된 정보를 user_info_handler 함수에서 sub-id를 저장하고, Django 시스템에서 로그인합니다.

profile
Hello Data and Python.

0개의 댓글