Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Django/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,11 @@
"USE_SESSION_AUTH": False, # 세션 인증 비활성화 (JWT 사용 시)
"JSON_EDITOR": True, # JSON 형식 편집기 활성화 (선택 사항)
}

# # 이메일 설정 (예: Gmail 사용)
# EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
# EMAIL_HOST = 'smtp.gmail.com'
# EMAIL_PORT = 587
# EMAIL_USE_TLS = True
# EMAIL_HOST_USER = '[email protected]'
# EMAIL_HOST_PASSWORD = 'your-email-password'
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 5.0.7 on 2024-08-02 03:12

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("app_user", "0002_alter_app_user_options_alter_app_user_managers_and_more"),
]

operations = [
migrations.AddField(
model_name="app_user",
name="email_verification_token",
field=models.CharField(blank=True, max_length=100),
),
migrations.AddField(
model_name="app_user",
name="is_email_verified",
field=models.BooleanField(default=False),
),
]
21 changes: 18 additions & 3 deletions Django/app_user/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
from django.contrib.auth.models import PermissionsMixin
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils.crypto import get_random_string # added common user login dependency
# from django.utils import timezone # added common user login dependency
from rest_framework_simplejwt.tokens import OutstandingToken


Expand Down Expand Up @@ -72,14 +74,23 @@ class App_User(AbstractBaseUser, PermissionsMixin):
updated_at = models.DateTimeField(auto_now=True) # 업데이트 시간
last_login_at = models.DateTimeField(null=True, blank=True) # 마지막 로그인 시간
is_active = models.BooleanField(default=True) # 계정 활성화 여부
role = models.CharField(
max_length=10, choices=UserRole.choices, default=UserRole.USER
)
role = models.CharField(max_length=10, choices=UserRole.choices, default=UserRole.USER)
is_email_verified = models.BooleanField(default=False) # added common user email verified
email_verification_token = models.CharField(max_length=100, blank=True) # added common user email token
email = models.EmailField(unique=True)
is_staff = models.BooleanField(default=False) # 스태프 권한
date_joined = models.DateTimeField(auto_now_add=True) # 가입일
is_superuser = models.BooleanField(default=False) # 최고 관리자 권한
refresh_token = models.TextField(blank=True, null=True) # 리프레시 토큰 저장 필드

USERNAME_FIELD = "user_id" # user_id를 사용자 이름으로 사용
REQUIRED_FIELDS = [
"name",
"nick_name",
"password_hash",
"username",
'email', # added common login email
] # 필수 필드 설정
objects = AppUserManager() # 커스텀 사용자 관리자 사용

USERNAME_FIELD = "user_id" # 로그인에 사용할 필드
Expand Down Expand Up @@ -115,6 +126,10 @@ def decrypt_refresh_token(self):
def __str__(self):
return self.user_id

# added common user generate email token
def generate_email_token(self):
self.email_verification_token = get_random_string(length=32)
self.save()

# --- SimpleJWT 관련 ---
class OutstandingToken(models.Model):
Expand Down
54 changes: 54 additions & 0 deletions Django/app_user/serializers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,58 @@
from rest_framework import serializers
from django.contrib.auth import get_user_model, authenticate
from django.contrib.auth.password_validation import validate_password

User = get_user_model()

class UserRegistrationSerializer(serializers.ModelSerializer):
password = serializers.CharField(write_only=True, required=True, validators=[validate_password])
password2 = serializers.CharField(write_only=True, required=True)
"""
added common user sign-up registration
"""
class Meta:
model = User
fields = ('email', 'username', 'nickname', 'password', 'password2')

def validate(self, attrs):
if attrs['password'] != attrs['password2']:
raise serializers.ValidationError({"password": "Password fields didn't match."})
return attrs

def create(self, validated_data):
user = User.objects.create(
username=validated_data['username'],
email=validated_data['email'],
nickname=validated_data['nickname']
)
user.set_password(validated_data['password'])
user.save()
return user

class UserLoginSerializer(serializers.Serializer):
username = serializers.CharField(required=False)
email = serializers.EmailField(required=False)
password = serializers.CharField()
"""
added common user sign-in
"""
def validate(self, data):
if not data.get('username') and not data.get('email'):
raise serializers.ValidationError("Must include either 'username' or 'email'.")
return data

class PasswordResetRequestSerializer(serializers.Serializer):
email = serializers.EmailField()

class PasswordResetConfirmSerializer(serializers.Serializer):
token = serializers.CharField()
new_password = serializers.CharField(write_only=True, validators=[validate_password])

from rest_framework_simplejwt.serializers import TokenRefreshSerializer

"""
added common user password reset management
"""

class CustomTokenObtainPairSerializer(TokenRefreshSerializer):
"""
Expand All @@ -11,3 +64,4 @@ def get_token(cls, user):
token = super().get_token(user)
token["user_id"] = str(user.id)
return token

10 changes: 10 additions & 0 deletions Django/app_user/urls.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from django.urls import include
from django.urls import path
from rest_framework.routers import DefaultRouter
from .views import (UserRegistrationView, UserLoginView, EmailVerificationView,
PasswordResetRequestView, PasswordResetConfirmView, UserLogoutView) # import added common user

from .views import BlacklistTokenUpdateView
from .views import CustomTokenObtainPairView
Expand All @@ -16,6 +18,14 @@
urlpatterns = [
# 뷰셋 URL 포함
path("", include(router.urls)),
path('register/', UserRegistrationView.as_view(), name='user-register'),
# added common login user-register path
path('login/', UserLoginView.as_view(), name='user-login'),
# added common login user-login path
path('verify-email/<str:token>/', EmailVerificationView.as_view(), name='verify-email'),
path('password-reset/', PasswordResetRequestView.as_view(), name='password-reset-request'),
path('password-reset/confirm/', PasswordResetConfirmView.as_view(), name='password-reset-confirm'),
path('logout/', UserLogoutView.as_view(), name='user-logout'),
# Google OAuth 로그인 관련 URL
path(
"google/login/", GoogleLogin.as_view(), name="google_login"
Expand Down
Loading