본문으로 바로가기

11.10 | DRF | CBV | sign in | signup | timeattack

category TIL 2022. 11. 10. 11:52

Feedback

  • user app damin 공식문서 찾아보기
  • access token의 Payload에  email과 token_message를 포함시키기

 

하나씩 흐름을 이해하면서 직접 코딩했지만 settings에서 AUTH_USER_MODEL = 'user.User’ 를 빼먹었다.

유저네임을 사용하지 않는 모델링을 했는데 계속 username이 떠서 뭔가 빼먹었나 싶어서 확인하면서 알아냈다.


email을 장고 username 대신 사용하면서  유니크값이 되었다. 모델링 수정으로 해결했다.


access token의 Payload에  email과 token_message를 포함시키는 연습이 필요할 것 같다. 처음 생각해보는 분야라 공부를 하고 til에 작성 할 예정이다.


USERNAME_FIELD 를 email로 커스텀 해줬다.

 


결과

 

로그인

 


회원가입


아래는 장고 공식문서를 참고해서 만든 코드입니다

# models.py

from django.db import models
from django.contrib.auth.models import (
    BaseUserManager, AbstractBaseUser
)


class UserManager(BaseUserManager):
    def create_user(self, email, password=None):

        if not email:
            raise ValueError('Users must have an email address')
        if not email:
            raise ValueError('Users must have an username')

        user = self.model(
            email=self.normalize_email(email),

        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password=None):

        user = self.create_user(
            email = email,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user



# Create your models here.
class User(AbstractBaseUser):
    email = models.EmailField(max_length=50, unique=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)
    objects = UserManager()
    USERNAME_FIELD = 'email'
    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        return self.is_admin
#serializers.py

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields= "__all__"

    #해싱 유저는 set패스워드 해줘야해서 구체적 명시 해줘야한다
    def create(self, validated_data): #기존 create 함수 오버라이드해서 만든다.
        user=super().create(validated_data) #이건 db에 전달 됐다
        # print(validated_data) # {'password': '123', 'email': '123123123@123123123.com'}
        password = user.password # 패스워드를 꺼낸다
        # print(user.password) #해싱 전 후 찍어본다
        user.set_password(password) #여긴 아직 전달안돼서 db에서는 해싱 안된게 저장됐을거다 아직
        # print(user.password)
        user.save()
        return user
    def update(self, validated_data): #업데이트도 똑같네 근데 이걸 어떻게 입력을 받지? 퓨어에서는 html에서 받았는데
        user= super().update(validated_data)
        password=user.password
        user.set_password(password)
        user.save()
        return user
#urls.py

from django.urls import path
from rest_framework_simplejwt.views import (
    TokenObtainPairView,
    TokenRefreshView,
)
from user import views

urlpatterns = [
    path('signup/', views.UserView.as_view(), name='user_view'),
    path('api/token/', views.CustomTokenObtainPairView.as_view(), name='token_obtain_pair'),
    path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
    ]
# views.py

from user.serializers import CustomTokenObtainPairSerializer, UserSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status



class CustomTokenObtainPairView(TokenObtainPairView):
    serializer_class=CustomTokenObtainPairSerializer


class UserView(APIView):
    def post(self, request):
        serializer=UserSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response({"message":"가입완료!"}, status=status.HTTP_201_CREATED)
        else:
            return Response({"message":f"${serializer.errors}"}, status=status.HTTP_400_BAD_REQUEST)