TIL 35 | Westagram Delete & Update

임종성·2021년 7월 29일
0

Django

목록 보기
15/17
post-thumbnail

Server는 로그인한 유저에게 JWT를 발급하고, 유저는 HTTP Request에 발급받은 JWT를 첨부해 Server에 보내주어 인가를 받는다. 인가를 통해 Westagram Post와 Comment의 삭제, 수정 기능을 구현해보자.

SignInDecorator Review

아래 코드는 User가 로그인이 필요한 기능을 사용하기 전 로그인 여부를 확인하는 Decorator를 구현한 코드이다.

# users.utils.py

def SignInDecorator(func):
    def wrapper(self, request, *args, **kwargs):
        try:
            # HTTP Request의 Header로부터 JWT를 받는다.
            access_token = request.headers.get('Authorization', None)          
            # JWT를 발급할때 사용한 SECRET_KEY와 알고리즘으로 Token을 Decode한다.
            payload      = jwt.decode(access_token, SECRET_KEY, algorithms='HS256')  
            # Decode한 JWT로부터 User ID를 알아내어 권한을 부여받은 User를 저장한다.
            user   	 = User.objects.get(id=payload['id'])                 
            request.user = user                                                
	# Token이 적합하지 않은 경우 INVALID_TOKEN 에러를 반환한다.
        except jwt.exceptions.DecodeError:                                        
            return JsonResponse({'message' : 'INVALID_TOKEN', 'Token':access_token }, status=400)
	# User가 존재하지 않은 경우 INVALIDE_USER 에러를 반환한다.
        except User.DoesNotExist:                                         
            return JsonResponse({'message' : 'INVALID_USER'}, status=400)

        return func(self, request, *args, **kwargs)

    return wrapper

Decorator 함수를 다시 살펴보면, 첨부받은 Token을 decode한 후에 request.user = user를 통해 Request에 user에 대한 정보를 담아 보내는 것을 알 수 있다. 이를 통해, 호출된 View는 어떤 User가 호출한 건지 알 수 있다.

게시물과 댓글의 삭제나 수정은 그 게시물이나 댓글을 작성한 유저만 삭제하거나 수정할 수 있도록 해야한다. Token을 Decode해서 유저의 정보를 얻어 권한이 없다면 에러를 반환하도록 하자.

Delete Post and Comment

# postings/views.py

class PostView(View):
    ...
    
    @SignInDecorator
    def delete(self, request, post_id):
    	# 삭제하고자 하는 Post의 존재 여부를 확인
        if not Post.objects.filter(id=post_id).exists():
            return JsonResponse({"MESSAGE":"NO_POST"}, status=400)
	# Post를 작성한 User가 삭제요청을 보낸 User인지 확인
        if Post.objects.get(id=post_id).user != request.user:
            return JsonResponse({"MESSAGE":"Unauthroized"}, status=403)
        # 삭제 요청한 Post 삭제
        Post.objects.filter(id=post_id).delete()

        return JsonResponse({"MESSAGE":"DELETE"}, status=200)
  • 삭제하고자 하는 Post가 Database에 존재하는지 확인한 후, 존재하지 않는다면 NO_POST 에러를 반환한다.
  • Decorator를 통해 request.user에 삭제요청을 한 User의 정보가 담겨있다. 이를 삭제하고자 요청한 Post의 작성자와 비교해 다르다면 Unauthorizaed 에러를 반환한다.
  • 적절한 권한을 가지고 있다면 Post를 삭제 한 후 DELETE 메시지를 반환한다.
  • Post(id=7)을 삭제


# postings/views.py

class CommentView(View):
    ...
    
    @SignInDecorator
    def delete(self, request, comment_id):
        if not Comment.objects.filter(id=comment_id).exists():
            return JsonResponse({"MESSAGE":"NO_COMMENT"}, status=400)

        if Comment.objects.get(id=comment_id).user != request.user:
            return JsonResponse({"MESSAGE":"Unauthroized"}, status=403)
        
        Comment.objects.filter(id=comment_id).delete()

        return JsonResponse({"MESSAGE":"DELETE"}, status=200) 
  • Comment도 Post와 같은 방식으로 DELETE 한다.

Update Post and Comment


# postings/views.py

class PostView(View):
    ...
    
    @SignInDecorator
    def put(self, request, post_id):
        try:
            data = json.loads(request.body)
            # 수정하고자 하는 Post 존재 여부 확인
            if not Post.objects.filter(id=post_id).exists():
                return JsonResponse({"MESSAGE":"NO_POST"}, status=400)
            # Post를 작성한 유저가 수정요청을 보낸 유저인지 확인
            if Post.objects.get(id=post_id).user != request.user:
                return JsonResponse({"MESSAGE":"Unauthroized"}, status=403)
	    # Post 수정
            Post.objects.filter(id=post_id).update(post = data['post'])
            return JsonResponse({"MESSAGE":"SUCCESS"}, status=201)
        except KeyError:
            return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)
  • 수정하고자 하는 Post가 Database에 존재하는지 확인한 후, 존재하지 않는다면 NO_POST 에러를 반환한다.

  • Decorator를 통해 request.user에 수정요청을 한 User의 정보가 담겨있다. 이를 수정하고자 요청한 Post의 작성자와 비교해 다르다면 Unauthorizaed 에러를 반환한다.

  • 적절한 권한을 가지고 있다면 Post를 수정한 후 SUCCESS 메시지를 반환한다.

  • Post(id=7)의 내용을 "안뇽하세요" 에서 "Update!"로 수정


# postings/views.py
class CommentView(View):
    ...
    
    @SignInDecorator
    def put(self, request, comment_id):
        try:
            data = json.loads(request.body)

            if not Comment.objects.filter(id=comment_id).exists():
                return JsonResponse({"MESSAGE":"NO_Comment"}, status=400)

            if Comment.objects.get(id=comment_id).user != request.user:
                return JsonResponse({"MESSAGE":"Unauthroized"}, status=403)

            Comment.objects.filter(id=comment_id).update(comment = data['comment'])
            return JsonResponse({"MESSAGE":"SUCCESS"}, status=201)
        except KeyError:
            return JsonResponse({"MESSAGE":"KEY_ERROR"}, status=400)
  • Comment도 Post와 같은 방식으로 Update한다.
profile
어디를 가든 마음을 다해 가자

0개의 댓글