@@ -0,0 +1,87 @@
+import re, json, bcrypt
+
+from django.views                 import View
+from django.http                  import JsonResponse, request
+from django.db.models.query_utils import Q
+from json.decoder                 import JSONDecodeError
+
+from user.utils  import LoginCheck
+from user.models import User
+
+class SignUpView(View):
+    def post(self, request):
+        try:
+            data = json.loads(request.body)
+
+            email         = data['email']
+            password      = data['password']
+            phone         = data.get('phone', None)
+            full_name     = data.get('full_name', None)
+            user_name     = data.get('user_name', None)
+            date_of_birth = data.get('date_of_birth', None)
+
+            if phone:
+                phone = phone.replace('-','')
+
+            REGEX_EMAIL    = '^[a-zA-Z0-9+-_.]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$'
+            REGEX_PASSWORD = '\S{8,20}'
+
+            if not re.match(REGEX_EMAIL,email):
+                return JsonResponse({'message':'EMAIL VALIDATION ERROR'}, status=400)
+            if not re.match(REGEX_PASSWORD,password):
+                return JsonResponse({'message':'PASSWORD VALIDATION ERROR'}, status=400)
+
+            if not User.objects.filter(email=email):
+                if phone and User.objects.filter(phone=phone):
+                    return JsonResponse({'message':'PHONE ALREADY EXISTS'}, status=400)
+                elif user_name and User.objects.filter(user_name=user_name):
+                    return JsonResponse({'message':'USER_NAME ALREADY EXISTS'}, status=400)
+            else:
+                return JsonResponse({'message':'EMAIL ALREADY EXISTS'}, status=400)
+
+            hashed_password = bcrypt.hashpw(password.encode('UTF-8'), bcrypt.gensalt()).decode()
+
+            User.objects.create(
+                email         = email,
+                phone         = phone,
+                full_name     = full_name,
+                user_name     = user_name,
+                password      = hashed_password,
+                date_of_birth = date_of_birth,
+            )
+
+            return JsonResponse({'message':'SUCCESS'}, status=200)     
+
+        except KeyError:
+            return JsonResponse({'message':'KEY ERROR'}, status=400)
+        except JSONDecodeError:
+            return JsonResponse({'message':'JSON DECODE ERROR'}, status=400)
+        except Exception as e:
+            print(e)
+
+
+class SignInView(View):
+    def post(self, request):
+        try:
+            data = json.loads(request.body)
+
+            user_id  = data['user_id']
+            password = data['password']
+
+            user= User.objects.get(Q(user_name=user_id)|Q(email=user_id)|Q(phone=user_id))
+
+            if user:
+                stored_password  = User.objects.get(Q(user_name=user_id)|Q(email=user_id)|Q(phone=user_id)).password
+                if not bcrypt.checkpw(password.encode('UTF-8'), stored_password.encode('UTF-8')):
+                    return JsonResponse({"message":"INVALID_PASSWORD"}, status=401)                
+            else:
+                return JsonResponse({"message":"INVALID_USER"}, status=401)   
+            
+            return JsonResponse({"message":"SUCCESS", "Authorization":LoginCheck(user.id)}, status=200)
+
+        except KeyError:
+            return JsonResponse({"message":"KEY_ERROR"}, status=400)
+        except JSONDecodeError:
+            return JsonResponse({'message':'JSON DECODE ERROR'}, status=400)
+        except Exception as e:
+            print(e)
\ No newline at end of file

리뷰: 이런식으로 exception 을 처리하시게 되면 어떤 exception 이 무엇때문에 `raise` 되었는지 확인하기가 어렵습니다. 그래서 exception 핸들러 추가해주실때는 위에서 `KeyError` 처리해주신것과 같이 명확하게 지정하여 처리해주셔야합니다. 

하지만 지금 단계에서 어떤 exception 이 발생할 수 있는지 모르는게 당연하기 때문에 이럴때는 그냥 여러가지 방법으로 호출해보면서 경험하여 추가해주시다보면 나중에는 메소드 하나를 추가할때 관련한 exception 을 처리해주는 로직을 바로 함께 작성할 수 있게 되실거에요! 😁