Ssul's Blog

[Django] username대신, email 사용하기, jwt로그인 1 본문

dev/기능구현

[Django] username대신, email 사용하기, jwt로그인 1

Ssul 2023. 12. 19. 16:37

장고의 user는 username을 기본으로 사용한다. 하지만, 요즘 회원가입/로그인은 소셜로그인 또는 email임.

 

그럼 선택의 기로에 선다.

쌩으로 user 모델 만들기 vs 장고 user상속후 만들기

이후 인증 등 다양한 내용을 구축하기에는 장고의 User를 상속받는 것이 맞는 것 같다.

그래서, User를 상속받되, email을 메인으로 사용하는 형태로 구현.

 

1. BaseUserManager 수정: 수정 안해도 되지만, 이후 관리자모드 사용하기에 피곤하지 않으려면, BaseUserManager부터 수정하자

class CustomUserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """
    def create_user(self, email, password, **extra_fields):
        """
        Create and save a User with the given email and password.
        """
        if not email:
            raise ValueError(_('The Email must be set'))
        email = self.normalize_email(email)
        #user생성시, email로 생성
        user = self.model(email=email, **extra_fields)
        user.set_password(password)
        user.save()
        return user

    def create_superuser(self, email, password, **extra_fields):
        """
        Create and save a SuperUser with the given email and password.
        """
        extra_fields.setdefault('is_staff', True)
        extra_fields.setdefault('is_superuser', True)
        extra_fields.setdefault('is_active', True)

        if extra_fields.get('is_staff') is not True:
            raise ValueError(_('Superuser must have is_staff=True.'))
        if extra_fields.get('is_superuser') is not True:
            raise ValueError(_('Superuser must have is_superuser=True.'))
            
            #슈퍼유저(관리자)도 username이 아닌, email로 생성 
        return self.create_user(email, password, **extra_fields)

 

2. User생성시, 장고의 AbstractUser상속받아서, email사용, username 미사용으로 셋팅

class User(AbstractUser):
    # abstractUser 기본필드 비활성화
    first_name = None  # first_name 필드 비활성화
    last_name = None   # last_name 필드 비활성화
    username = None		#username필드 비활성화
    
    # password는 AbstractUser로 사용
    email = models.EmailField(unique=True)

    nickname = models.CharField(max_length=255, verbose_name='닉네임')
    biz_message_phone_number = models.CharField(max_length=255, verbose_name='비즈메시지 수신 휴대폰번호')
    # 서비스에서 필요한 User내용 넣기
    

    # USERNAME_FIELD는 사용자를 식별하는 데 사용되는 필드, 
    USERNAME_FIELD = "email"
    EMAIL_FIELD = "email"
    
    # REQUIRED_FIELDS는 createsuperuser 관리 명령어 실행 시 필요한 필드 목록
    # 나는 미입력했으므로, email과 password만 필요
    REQUIRED_FIELDS = []

	#위에서 만든 커스텀유저매니저 연결
    objects = CustomUserManager()

 

3. 로그인 구현 기획

로그인 구현은 쿠키, 세션, 토큰 방식.

쿠키, 세션은 많이 해봤으니, 토큰 방식으로 결정.

djangorestframework-simplejwt 사용하기

 

4. djangorestframework-simplejwt 셋팅

pip install djangorestframework-simplejwt
#settings.py

INSTALLED_APPS = [
    ...
    'rest_framework_simplejwt.token_blacklist',
]

REST_FRAMEWORK = {
    ...
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_simplejwt.authentication.JWTAuthentication',
    ),
}

SIMPLE_JWT = {
   'ACCESS_TOKEN_LIFETIME': timedelta(minutes=5),
   'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
		# 리프레쉬 토큰 발급시 새로운것으로 할지?
   'ROTATE_REFRESH_TOKENS': False,
   'BLACKLIST_AFTER_ROTATION': True,
   ...
}