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
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ db.sqlite3
db.sqlite3-journal
media
migrations/
venv/
venv/
.DS_Store
.idea
Binary file not shown.
Binary file not shown.
Binary file removed backend/djangoreactapi/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file removed backend/djangoreactapi/__pycache__/wsgi.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/__init__.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/admin.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/apps.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/models.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/serializers.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/urls.cpython-310.pyc
Binary file not shown.
Binary file removed backend/post/__pycache__/views.cpython-310.pyc
Binary file not shown.
22 changes: 0 additions & 22 deletions backend/post/migrations/0001_initial.py

This file was deleted.

Binary file not shown.
Binary file not shown.
19 changes: 19 additions & 0 deletions 김영승/backend/djangoreactapi/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import jwt
from rest_framework import permissions
import rest_framework_simplejwt

from user.models import User


class IsOwnerOrReadOnly(permissions.BasePermission):

def has_object_permission(self, request, view, obj):
# 읽기 권한 요청일 경우 허용
if request.method in permissions.SAFE_METHODS:
return True
header_token = request.META.get('HTTP_AUTHORIZATION', None)
token = header_token.split(' ')
payload = jwt.decode(token, "secret", algorithms=["HS256"])
username = User.objects.filter(user_id=payload['user_id']).get('username')
# 요청자(request.user)가 객체(Post)의 created_user 와 동일한지 확인
return obj.created_user == username
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.2/ref/settings/
"""

from datetime import timedelta
from pathlib import Path

# Build paths inside the project like this: BASE_DIR / 'subdir'.
Expand Down Expand Up @@ -37,22 +37,38 @@
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework_simplejwt',


# django app
'post',
'post.apps.PostConfig',
'user.apps.UserConfig',

# drf
'rest_framework',
]

REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny',
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}

REST_USE_JWT = True

SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=2),
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'TOKEN_USER_CLASS': 'user.User', #유저 모델 연결
}

MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@

urlpatterns = [
path('api/admin/', admin.site.urls),
path('api/post/', include('post.urls'))
path('api/post/', include('post.urls')),
path('api/user/', include('user.urls')),
]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
5 changes: 4 additions & 1 deletion backend/post/models.py → 김영승/backend/post/models.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
from django.db import models

from user.models import User


# Create your models here.

class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
# created_user = models.ForeignKey(User, on_delete=models.CASCADE(), db_column="created_user", to_field="username")
created_user = models.ForeignKey(User, on_delete=models.CASCADE, db_column="created_user", to_field="username",default='')

def __str__(self):
return self.id
File renamed without changes.
File renamed without changes.
File renamed without changes.
18 changes: 14 additions & 4 deletions backend/post/views.py → 김영승/backend/post/views.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
import jwt
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.views import APIView
from rest_framework.generics import ListCreateAPIView, get_object_or_404
from rest_framework.response import Response
from rest_framework.exceptions import NotFound
from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST

from djangoreactapi.permissions import IsOwnerOrReadOnly
from .models import Post
from .serializers import PostSerializer, PostDetailSerializer


class ListPostView(ListCreateAPIView):
permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
# 00-01 post 생성
queryset = Post.objects.all()
serializer_class = PostDetailSerializer
Expand All @@ -19,7 +24,9 @@ def list(self, request):
return Response(serializer.data, status=HTTP_200_OK)



class DetailPostView(APIView):
permission_classes = [IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly]
# 00-02 post 상세 조회
def get(self, request, pk):
post = get_object_or_404(Post, id=pk)
Expand All @@ -36,8 +43,11 @@ def put(self, request, pk):
return Response(serializer.data, status=HTTP_200_OK)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)

"""
작성자만 삭제할 수 있도록 구현
def delete(self, request):
def delete(self, request, pk):
# 토큰을 받아서 user인증하는 방법 구현중
token = request.GET('token')
print(token)
# payload = jwt.decode(token,)
post = get_object_or_404(Post, id=pk)
"""
post.delete()
# serializer = PostSerializer(post)
File renamed without changes.
4 changes: 4 additions & 0 deletions 김영승/backend/user/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from django.contrib import admin
from .models import User

admin.site.register(User)
6 changes: 6 additions & 0 deletions 김영승/backend/user/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.apps import AppConfig


class UserConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'user'
6 changes: 6 additions & 0 deletions 김영승/backend/user/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from django.db import models

# Create your models here.
class User(models.Model):
username = models.CharField(max_length=20, unique=True)
password = models.CharField(max_length=20)
89 changes: 89 additions & 0 deletions 김영승/backend/user/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
from rest_framework import serializers
from rest_framework_simplejwt.tokens import RefreshToken

from user.models import User


class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'password']


class JWTSignupSerializer(serializers.ModelSerializer):

username = serializers.CharField(
required=True,
write_only=True,
max_length=20
)

password = serializers.CharField(
required=True,
write_only=True,
max_length=20,
)

class Meta(object):
model = User
fields = ['username', 'password']

def save(self, request):
user = super().save()

user.name = self.validated_data['username']
# AbstractUser 상속받아서 만든 User모델의 경우 set_password()를 사용할 수 있음
# user.set_password(self.validated_data['password'])
user.password = self.validated_data['password']
user.save()

return user

def validate(self, data):
username = data.get('username', None)
print(User.objects.all())
if User.objects.filter(username=username).exists():
raise serializers.ValidationError("user already exists")

return data


class JWTLoginSerializer(serializers.ModelSerializer):
username = serializers.CharField(
required=True,
write_only=True,
)

password = serializers.CharField(
required=True,
write_only=True,
# style={'input_type': 'password'}
)

class Meta(object):
model = User
fields = ['username', 'password']

def validate(self, data):
username = data.get('username', None)
password = data.get('password', None)

if User.objects.filter(username=username).exists():
user = User.objects.get(username=username)

if user.password != password:
raise serializers.ValidationError("wrong password")
else:
raise serializers.ValidationError("user account not exist")

token = RefreshToken.for_user(user)
refresh = str(token)
access = str(token.access_token)

data = {
'user': user,
'refresh': refresh,
'access': access,
}

return data
3 changes: 3 additions & 0 deletions 김영승/backend/user/tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from django.test import TestCase

# Create your tests here.
15 changes: 15 additions & 0 deletions 김영승/backend/user/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.urls import path
from rest_framework_simplejwt.views import TokenObtainPairView
from rest_framework_simplejwt.views import TokenRefreshView
from rest_framework_simplejwt.views import TokenVerifyView
from user import views

urlpatterns = [
# 로그인/회원가입
path('login/', views.JWTLoginView.as_view()),
path('signup/', views.JWTSignupView.as_view()),
# 토큰
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh', TokenRefreshView.as_view(), name='token_refresh'),
path('token/verify', TokenVerifyView.as_view(), name='token_verify'),
]
45 changes: 45 additions & 0 deletions 김영승/backend/user/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework_simplejwt.tokens import RefreshToken

from user.serializers import JWTSignupSerializer, JWTLoginSerializer, UserSerializer


class JWTSignupView(APIView):
serializer_class = JWTSignupSerializer

def post(self, request):
serializer = self.serializer_class(data=request.data)

if serializer.is_valid(raise_exception=False):
user = serializer.save(request)

token = RefreshToken.for_user(user)
refresh = str(token)
access = str(token.access_token)
return Response({'user': UserSerializer(user).data,
'access': access,
'refresh': refresh}, status=status.HTTP_200_OK)
else:
return Response(status=status.HTTP_403_FORBIDDEN)


class JWTLoginView(APIView):
serializer_class = JWTLoginSerializer

def post(self, request):
serializer = self.serializer_class(data=request.data)

if serializer.is_valid(raise_exception=False):
user = serializer.validated_data['user']
access = serializer.validated_data['access']
refresh = serializer.validated_data['refresh']

return Response({
'user': UserSerializer(user).data,
'access': access,
'refresh': refresh}, status=status.HTTP_200_OK)

else:
return Response(status=status.HTTP_403_FORBIDDEN)