@@ -8,12 +8,12 @@ from common.utils.codeManger import set_expire
|
||||
class CertificationCode(BaseModel):
|
||||
use_type = models.CharField(choices=CertificateCodeUseType.choices, max_length=5)
|
||||
code = models.CharField(max_length=6)
|
||||
expire_at = models.DateTimeField(default=set_expire(minutes=5))
|
||||
expire_at = models.DateTimeField(default=set_expire)
|
||||
is_used = models.BooleanField(default=False)
|
||||
identifier = models.CharField(max_length=40)
|
||||
|
||||
class InviteCode(BaseModel):
|
||||
use_type = models.CharField(choices=InviteCodeUseType.choices, max_length=5)
|
||||
code = models.CharField(max_length=10)
|
||||
expire_at = models.DateTimeField(default=set_expire(minutes=10080)) # 일주일은 10080분
|
||||
expire_at = models.DateTimeField(default=set_expire) # 일주일은 10080분
|
||||
identifier = models.CharField(max_length=40)
|
||||
|
||||
BIN
requirements.txt
BIN
requirements.txt
Binary file not shown.
@@ -28,18 +28,20 @@ class UserManager(BaseUserManager):
|
||||
|
||||
class User(BaseModel, AbstractBaseUser, PermissionsMixin):
|
||||
email = models.EmailField(unique=True)
|
||||
is_email_verified = models.BooleanField(default=False)
|
||||
realname = models.CharField(max_length=10, blank=True)
|
||||
# is_email_verified = models.BooleanField(default=False)
|
||||
is_plers_terms_of_service = models.BooleanField(default=False)
|
||||
is_terms_of_service_colio = models.BooleanField(default=False)
|
||||
is_consent_personal_info = models.BooleanField(default=False)
|
||||
is_consent_third_party_sharing = models.BooleanField(default=False)
|
||||
is_consent_marketing = models.BooleanField(default=False)
|
||||
phone = models.CharField(max_length=11, blank=True)
|
||||
is_phone_verified = models.BooleanField(default=False)
|
||||
# is_phone_verified = models.BooleanField(default=False)
|
||||
nickname = models.CharField(max_length=20, blank=True)
|
||||
gender = models.CharField(choices=GenderChoices.choices, max_length=1, blank=True)
|
||||
birth_date = models.CharField(max_length=10, blank=True)
|
||||
custom_url = models.CharField(max_length=20, blank=True)
|
||||
is_custom_url = models.BooleanField(default=False)
|
||||
job_and_interests = ArrayField(models.CharField(max_length=20), default=list, blank=True)
|
||||
skills = ArrayField(models.CharField(max_length=20), default=list, blank=True)
|
||||
external_links = ArrayField(models.TextField(), default=list, blank=True)
|
||||
@@ -47,7 +49,7 @@ class User(BaseModel, AbstractBaseUser, PermissionsMixin):
|
||||
profile_image = models.ImageField(upload_to='', blank=True)
|
||||
|
||||
is_staff = models.BooleanField(default=False)
|
||||
is_active = models.BooleanField(default=False)
|
||||
is_active = models.BooleanField(default=True)
|
||||
|
||||
objects = UserManager()
|
||||
|
||||
|
||||
23
users/serializers.py
Normal file
23
users/serializers.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from .models import *
|
||||
from rest_framework import serializers
|
||||
|
||||
class JoinSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = User
|
||||
fields = [
|
||||
'email',
|
||||
'password',
|
||||
'is_plers_terms_of_service',
|
||||
'is_terms_of_service_colio',
|
||||
'is_consent_personal_info',
|
||||
'is_consent_third_party_sharing',
|
||||
'is_consent_marketing',
|
||||
'realname',
|
||||
'phone',
|
||||
'nickname',
|
||||
'gender',
|
||||
'birth_date'
|
||||
]
|
||||
|
||||
def create(self, validated_data):
|
||||
return User.objects.create_user(**validated_data)
|
||||
12
users/urls.py
Normal file
12
users/urls.py
Normal file
@@ -0,0 +1,12 @@
|
||||
from django.urls import path
|
||||
|
||||
from .views import *
|
||||
|
||||
app_name = 'users'
|
||||
|
||||
urlpatterns = [
|
||||
path('refresh-token/', RefreshAPIView.as_view()),
|
||||
path('join/', JoinAPIView.as_view()),
|
||||
path('login/', LoginAPIView.as_view()),
|
||||
path('check/', NicknameAPIView.as_view()),
|
||||
]
|
||||
@@ -1,3 +1,97 @@
|
||||
from django.shortcuts import render
|
||||
from django.shortcuts import get_object_or_404
|
||||
|
||||
# Create your views here.
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer, TokenRefreshSerializer
|
||||
from rest_framework_simplejwt.tokens import RefreshToken
|
||||
from rest_framework_simplejwt.exceptions import TokenError, InvalidToken
|
||||
|
||||
from rest_framework import status
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.permissions import AllowAny, IsAuthenticated
|
||||
|
||||
from django.contrib.auth import authenticate
|
||||
|
||||
from .models import *
|
||||
from .serializers import *
|
||||
|
||||
|
||||
class RefreshAPIView(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
# access token 재발급
|
||||
def post(self, request):
|
||||
refresh = request.COOKIES.get("refresh")
|
||||
if not refresh:
|
||||
return Response({"message": "No refresh token"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
if request.data.get("user_id", None) != RefreshToken(refresh).payload.get("user_id", None):
|
||||
return Response({"message": "Wrong userid"}, status=status.HTTP_400_BAD_REQUEST)
|
||||
try:
|
||||
serializer = TokenRefreshSerializer(data={'refresh': refresh})
|
||||
if serializer.is_valid():
|
||||
res = Response({"access": serializer.validated_data['access']}, status=status.HTTP_200_OK)
|
||||
res.set_cookie("refresh", serializer.validated_data['refresh'], httponly=True, samesite="Lax", secure=True)
|
||||
return res
|
||||
except TokenError as e:
|
||||
return Response({"message": f"Invalid token: {e}"}, status=status.HTTP_401_UNAUTHORIZED)
|
||||
|
||||
|
||||
|
||||
class JoinAPIView(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
# 회원가입
|
||||
def post(self, request):
|
||||
serializer = JoinSerializer(data=request.data)
|
||||
if serializer.is_valid():
|
||||
serializer.save()
|
||||
res = Response({"message": "회원가입이 완료되었습니다."}, status=status.HTTP_200_OK)
|
||||
return res
|
||||
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
class LoginAPIView(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
# 로그인
|
||||
def post(self, request):
|
||||
email=request.data.get("email", None)
|
||||
password=request.data.get("password", None)
|
||||
# 로그인 전 쿠키에 있는 리프레시 토큰 무효화
|
||||
try:
|
||||
refresh = request.COOKIES.get('refresh')
|
||||
if refresh:
|
||||
refresh_token = RefreshToken(refresh)
|
||||
refresh_token.blacklist()
|
||||
except TokenError as e:
|
||||
pass
|
||||
|
||||
if user := authenticate(email=email, password=password):
|
||||
serializer = TokenObtainPairSerializer(data={'email': email, 'password': password})
|
||||
# id, 비번 맞나 틀리나 검사
|
||||
if serializer.is_valid():
|
||||
res = Response(
|
||||
{
|
||||
"message": "login success",
|
||||
"user_id": user.id,
|
||||
"nickname": user.nickname,
|
||||
"access": serializer.validated_data['access'],
|
||||
"is_custom_url": user.is_custom_url
|
||||
},
|
||||
status=status.HTTP_200_OK,
|
||||
)
|
||||
res.set_cookie("refresh", serializer.validated_data['refresh'], httponly=True, samesite="Lax", secure=True)
|
||||
return res
|
||||
else:
|
||||
return Response(serializer.errors)
|
||||
else: # id, 비번 둘 중 하나가 틀렸을 때
|
||||
return Response({"message": "아이디 혹은 비밀번호가 맞지 않습니다."}, status=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
class NicknameAPIView(APIView):
|
||||
permission_classes = [AllowAny]
|
||||
# 닉네임 중복 체크
|
||||
def get(self, request):
|
||||
nickname = request.GET.get('nickname', None)
|
||||
if not nickname:
|
||||
return Response({"message": "닉네임을 입력하세요."}, status=status.HTTP_400_BAD_REQUEST)
|
||||
try:
|
||||
get_object_or_404(User, nickname=nickname)
|
||||
return Response({"message": "해당 닉네임은 사용할 수 없습니다."}, status=status.HTTP_400_BAD_REQUEST)
|
||||
except:
|
||||
return Response({"message": "사용할 수 있는 닉네임입니다."}, status=status.HTTP_200_OK)
|
||||
|
||||
Reference in New Issue
Block a user