WESTAGRAM(2,3)

On a regular basis·2021년 5월 8일
0

WESTAGRAM

목록 보기
2/2
post-thumbnail

🐙 장고를 활용한 WESTAGRAM 과제 🐙

🥲 2. 회원가입 구현

account앱 생성
User class 생성
models.py urls.py, views.py 모두 작성
필수 요구사항 입력
비밀번호를 bcrypt (단방향 해쉬 + salting + key stretching) 처리
토큰발행!

🥲 3. 로그인 구현

이메일로 로그인할 수 있음
실패시 에러 반환
성공시 200 OK 반환

🥲 CODE?

modesl.py

from django.db import models
class User(models.Model):
    email        = models.EmailField(max_length=80)
    password     = models.CharField(max_length=80)
    phone_number = models.CharField(max_length=80, null = True)
    nickname     = models.CharField(max_length=80, null = True)

    class Meta:
        db_table: "users"
  • (from 앱.models import 클래스) 참조할 때 꼭 확인하기!
  • ForeignKey 쓸때, ('클래스명')

부모 urls.py

from django.urls import path, include

urlpatterns = [
    path('account', include('account.urls')),
    path('posting', include('posting.urls'))
   ]
  • 부모 urls.py에서는 path와 include 모두를 정해주어야함.
  • path에서 앱이름이 먼저 나오고, 그다음 include에 앱.urls!

아들 urls.py

from django.urls import path
from account.views import SignupViews, SigninViews

urlpatterns = [
    path('/signup', SignupViews.as_view()),
    path('/signin', SigninViews.as_view())
]
  • 특정 앱(account)의 views에서 특정 뷰(SignupViews, SigninViews)를 불러올 것.
  • path뒤에는 요청할 때 넣는 주소로 /signup, /signin으로 적어주면 됨.

Views.py

import json
import bcrypt
import jwt

from django.views   import View
from django.http    import JsonResponse
from account.models import User
class SignupViews(View):
    def post(self, request):
        try:
            data = json.loads(request.body)
            email        = data['email']
            password     = data['password']
            phone_number = data.get('phone_number')
            nickname     = data.get('nickname')
            
            if email == "" or password == "":
                return JsonResponse({'MESSAGE':'KEY_ERROR'}, status = 400)

            if data['email'].count('@') == 0 or data['email'].count('.') == 0:
                return JsonResponse({'MESSAGE' : 'KEY_ERROR'}, status = 400) 

            if User.objects.filter(phone_number=data.get('phone_number')).exists()\
                and data.get('phone_number') != None:
                return JsonResponse({'MESSAGE': 'ALREADY_EXISTS'}, status = 400)

            if User.objects.filter(nickname=data.get('nickname')).exists()\
                and data.get('nickname') != None:
                return JsonResponse({'MESSAGE' : 'ALREADY_EXISTS'}, status = 400)

            if User.objects.filter(email=data['email']).exists():\
                return JsonResponse({"MESSAGE" : 'ALREADY_EXISTS'}, status = 400)

            PASSWORD_LENGTH = 8
            if len(data['password']) < PASSWORD_LENGTH:
                return JsonResponse({'MESSAGE' : 'INVALID_PASSWORD'}, status = 400)
            
            hashed_password = bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8') 

            User.objects.create(
                email         = email,
                password      = hashed_password,
                nickname      = nickname,
                phone_number  = phone_number
            )

            return JsonResponse({'Message' : 'SUCCESS'}, status = 201)
        except KeyError:
            return JsonResponse({'MESSAGE' : 'KEY_ERROR'}, status = 400)

class SigninViews(View):
    def post(self, request):
        try:
            data         = json.loads(request.body)
            email        = data['email']
            password     = data['password']
            
            if not User.objects.filter(email=email).exists():
                return JsonResponse({"MESSAGE" : "INVALID_USER"}, status=400)
            
            user = User.objects.get(email=email)
                
            if bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8')):
                token = jwt.encode({'user_id' : user.id}, 'secret', algorithm = 'HS256')
                return JsonResponse({"TOKEN" : token, "MESSAGE" : "SUCCESS!"}, status=200)
            else:
                return JsonResponse({"MESSAGE" : "INVALID_USER"}, status=400)

        except KeyError:
            return JsonResponse({"MESSAGE" : "KEY_ERROR"}, status=400)
  • from 앱.models import 클래스!!!!!!!!!!!!!
  • from과 import 헷갈리지 말기, 어디에서 무엇을 갖고와야하는지 명확하게 구분하고 있기.
  • encode해서 다 암호화해놨는데 다시 decode하는 것은 b까지 패스워드로 인식하지 않도록 하기 위한 것이니까 decode빼먹지 말고 해주기.
  • data['email']과 data.get['email']의 차이? 전자는 request들어온 email을 의미하는데 그 값이 들어오지 않는다면 키에러를 발생시킨다. 하지만 후자는 값이 없더라도 키에러가 들어오지 않고 none값을 기본적으로 갖고, 내가 별도로 값을 지정해준다면 그 값을 가지게 된다. 중요!

🥲 프론트랑 서버 통신할 때!

  • 나 혼자할 때는? python manage.py runserver
  • 다른 사람들과 함께 서버 사용할 때는? python manage.py runserver 0:8000 (중요해!)
  • 내 IP 확인은? terminal창에 ipconfig getifaddr en0 쳐주기.
  • 프론트에게 어떻게 주소를 알려줄까? http://IP주소:8000/path

🥲 Westagram을 마치면서...

  1. 과제가 무엇인지 정확하게 확인하는 것!🥑 -> 내가 해야하는 것이 무엇인지 파악하는 것이 너무 중요하다. 안그럼 산으로 가고 시간+노력 낭비이니까 -> 그 다음 우선순위를 정하고 하나씩 처리하기.

  2. 손에 익히고 또 손에 익히기!🥕 -> 무에서 유를 창조하고 싶어서 개고생을 했다. 터미널을 혼자 힘으로 다 채우고 싶었나보다. 절대 그럴 수 없고 그래서도 안되는데 이해한답시고 시간 너무 많이 버렸고 진도도 못맞췄다. 무조건 따라해보고 먼저 쳐보고 하나씩 이해해가는 걸로 해야겠다. 아직 문과충의 버릇을 못버린 것 같다.

  3. 이건 사소하지만 내게 너무 필요한 tip!🍍 (de 승무님)

x 앞에 빈칸을 두느냐 마느냐의 작은 차이로 저렇게 다른 결과가 나온다. 아주 작은 것 하나에도 의미가 있고 담긴 요청이 있다. 결과 값이 달라진다는 건 정말 엄청난 일이다. 무엇이든 쉽게 지나치지 말아야겠다. 조금 더 꼼꼼하게 확인하기.

  1. 정확하게 아는 것이 정말 중요하다!🍋 모르면 아는 척하고 넘어가지 말기. 그러면 더뎌도 늦는건 아닐 수 있으니까. 근데 정말 이게 어렵다.
profile
개발 기록

0개의 댓글