User Profile
# users/serializers.py
class PrivateUserSerializer(ModelSerializer):
class Meta:
model=User
exclude = (
"password",
"is_superuser",
"id",
"is_staff",
"is_active",
"first_name",
"last_name",
"groups",
"user_permissions",
)
#users/ views.py
#.../api/v1/users/me 내 프로필만 보는 url
class Me(APIView):
permission_classes = [IsAuthenticated] #자세한 정보는 로그인한 본인에게만 보여야하므로.
def get(self, request): #유저 정보 보기
user= request.user
serializer = serializers.PrivateUserSerializer(user)
return Response(serializer.data)
def put(self, request): #유저 정보 수정
user = request.user
serializer = serializers.PrivateUserSerializer(user, data=request.data, partial=True,)
if serializer.is_valid():
user = serializer.save()
serializer = serializers.PrivateUserSerializer(user)
return Response(serializer.data)
else:
return Response(serializer.errors)
Create User
#users/ views.py
#.../api/v1/users
class Users(APIView): #유저 생성
def post(self, request):
password = request.data.get('password')
if not password: #유저가 password를 보내지 않으면.
raise ParseError
serializer = serializers.PrivateUserSerializer(data=request.data)
if serializer.is_valid():
user = serializer.save()
user.set_password(password) #그냥 저장하면 raw_password가 됨. 우리는 hash화된 password가 필요함.
user.save()
serializer = serializers.PrivateUserSerializer(user)
return Response(serializer.data)
else:
return Response(serializer.errors)
serializer는 위에서 만든 'PrivateUserSerializer'를 사용한다.
우리가 유저를 만들 때, 따로 설정을 하지 않아도 ModelSerializer가 그 유저의 이름이 이미 존재하는 것인지 확인해준다. 그래서 이것에 대해서는 validation을 하지 않아도 된다.
Username
from django.urls import path
from . import views
urlpatterns = [
path("", views.Users.as_view()),
path("me", views.Me.as_view()),
path("@<str:username>", views.PublicUser.as_view()),
]
url을 입력하면, urls.py에서 path에서 위에서부터 맞는 것을 찾기 때문에, path를 적는 순서도 중요하다.
이를 예방하기 위해, @를 붙이는 방법을 활용한다.
#users/views.py
#.../api/v1/users/username 공개 프로필
class PublicUser(APIView):
def get(self, request, username):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise NotFound
serializer = serializers.PublicUserSerializer(user)
return Response(serializer.data)
Change Password
#users/views.py
#.../api/v1/users/change-password
class ChangePassword(APIView):
permission_classes = [IsAuthenticated]
def put(self, request):
user = request.user
old_password = request.data.get("old_password")
new_password = request.data.get("new_password")
if not old_password or not new_password:
raise ParseError
if user.check_password(old_password):
user.set_password(new_password)
user.save()
return Response(status=status.HTTP_200_OK)
else:
raise ParseError
password를 그냥 저장해두면 안전하지 않다. 그래서 'set_password()'를 사용하여 해시화해서 저장할 수 있다.
old-password가 맞는지 확인하는 데에 django는 좋은 utility를 가지고 있다. 원래 password는 해시화되어 저장되어 있어서, 그냥 맞는지 확인할 수 없다. 그래서 'check_password()'를 사용한다.
LogIn, LogOut
#users/views.py
#.../api/v1/users/log-in .../api/v1/users/log-out
from django.contrib.auth import authenticate, login, logout
class LogIn(APIView):
def post(self,request):
username = request.data.get('username')
password = request.data.get('password')
if not username or not password:
raise ParseError
user = authenticate( #username과 password가 맞지 않으면 user를 리턴하지 않음.
request,
username=username,
password=password,
)
if user:
login(request, user)
return Response({"ok":"Welcome!"})
else:
return Response({"error":"Wrong Password"})
class LogOut(APIView):
permission_classes = [IsAuthenticated]
def post(self, request):
logout(request)
return Response({"ok":"bye!"})
'from django.contrib.auth import authenticate,login,logout' 에서
'authenticate': 만약 username과 password가 맞으면, django는 그에 맞는 user를 리턴한다.
'login': 유저를 로그인시켜주는 function. 로그인시켜줄 user와 request를 보내면 django가 브라우저가 필요한 쿠키와 token등, 중요한 것은 다 자동으로 만들어준다.
'노마드 코더 Airbnb 클론 코딩' 카테고리의 다른 글
노마드 코더 에어비앤비 클론 코딩 #16 API TESTING (0) | 2022.12.07 |
---|---|
노마드 코더 에어비앤비 클론 코딩 #15 AUTHENTICATION (0) | 2022.12.01 |
노마드 코더 에어비앤비 클론 코딩 #11 Rest API - 2 (1) | 2022.11.19 |
노마드 코더 에어비앤비 클론 코딩 #11 Rest API - 1 (0) | 2022.11.08 |
노마드 코더 에어비앤비 클론 코딩 #10 Django Rest Framework (1) | 2022.11.05 |