LANEIGE clone 프로젝트 과정(2)

JM·2020년 7월 19일
0

Project

목록 보기
6/11

account.models.py

from django.db import models

from product.models import Product

class Account(models.Model):
    name           = models.CharField(max_length = 50)
    birthdate      = models.CharField(max_length = 50)
    gender         = models.ForeignKey("Gender", on_delete = models.SET_NULL,null = True)
    password       = models.CharField(max_length = 1000, null = True)
    phone_number   = models.CharField(max_length = 50, null = True)
    user_email     = models.CharField(max_length = 100)
    is_social_user = models.CharField(max_length = 100 )
    
    class Meta:
        db_table = "accounts"

class Gender(models.Model):
    name   = models.CharField(max_length = 20)
    
    class Meta:
        db_table = "genders"
  • 회원 가입을 구현하기 위하여 다음과 같이 models.py를 구성하였다.
  • password와 phone_number의 경우 social_login 유저들의 경우 해당 정보들을 알 수가 없어 null=true로 설정을 하였다.

account.views.py

import json
import jwt
import bcrypt
import re
import requests

from django.views           import View
from django.core.exceptions import ValidationError
from django.http            import (
    JsonResponse,
    HttpResponse
)

from laneige.settings        import (
    SECRET_KEY,
    ACCESS_KEY,
    NAVER_SECRET_KEY,
    NAVER_SMS_URI,
    NAVER_URI,
    ALGORITHM
)

from .models                import (
    Account,
    Gender
)
from .utils  import send_sms

from threading import Timer
from multiprocessing import Process
    
class SignUpView(View):
    def post(self, request):
        account_data = json.loads(request.body)
        
        try:
            if Account.objects.filter(user_email=account_data['user_email']).exists():
                return JsonResponse({'message':'ALREADY_EXISTS'},status = 400)
            
            else :
                hashed_password = bcrypt.hashpw(account_data['password'].encode('utf-8'), bcrypt.gensalt())
                user = Account.objects.create(
                    name            = account_data['name'],
                    password        = hashed_password.decode('utf-8'),
                    birthdate       = account_data['birthdate'],
                    gender          = Gender.objects.get(name=account_data['gender']),
                    phone_number    = account_data['phone_number'],
                    user_email      = account_data['user_email']
                )
                
                send_sms(account_data['phone_number'])
        
                return HttpResponse(status = 200)
                
        except KeyError:
            return JsonResponse({'message' : 'INVALID_KEYS'}, status = 400)
        
class SignInView(View):
    def post(self, request):
        account_data = json.loads(request.body)
        
        try:
            if Account.objects.filter(user_email=account_data['user_email']).exists():
                account = Account.objects.get(user_email=account_data['user_email'])
                
                if bcrypt.checkpw(account_data['password'].encode('utf-8'), account.password.encode('utf-8')):
                    token = jwt.encode({'user_id' : account.id }, SECRET_KEY, algorithm = ALGORITHM)
                    return JsonResponse({ 'access_token' : token.decode('utf-8')}, status=200)
                 
                return JsonResponse({ 'message' : 'WRONG_PASSWORD'}, status=400)    
            return JsonResponse({ 'message' : 'NOT_EXIST_EMAIL'}, status=401)

        except KeyError:
            return JsonResponse({ 'message' : 'INVALID_KEYS'}, status=400)
        
class KakaoView(View):
    def post(self, request):
        access_token = request.headers['Authorization']

        kakao_request = requests.get(
            'https://kapi.kakao.com/v2/user/me',
            headers = {
                "Host"          : "kapi.kakao.com",
                "Authorization" : f"Bearer {access_token}",
                "Content-type"  : "application/x-www-from-urlencoded;charset=utf-8"
            }
        ,timeout = 2)
        
        kakao_id        = kakao_request.json().get('id')
        kakao_properties  = kakao_request.json().get('properties')
        kakao_account     = kakao_request.json().get('kakao_account')
        
        try:
            if Account.objects.filter(is_social_user = kakao_id).exists():
                user    = Account.objects.get(is_social_user = kakao_id)
                token   = jwt.encode({'user_id' : user.id }, SECRET_KEY, algorithm = ALGORITHM)
                return JsonResponse({"access_token":token.decode('utf-8')}, status = 200)

            else:
                Account(
                    is_social_user         = kakao_id,
                    gender                 = Gender.objects.get(name=kakao_account['gender']),
                    user_email             = kakao_account['email'],
                    name                   = kakao_properties['nickname'],
                    birthdate              = kakao_account['birthday']
                ).save()

                user    = Account.objects.get(is_social_user = kakao_id)
                token   = jwt.encode({'user_id' : user.id }, SECRET_KEY, algorithm = ALGORITHM)
                return JsonResponse({"access_token":token.decode('utf-8')}, status = 200)
                
        except KeyError:
            return JsonResponse({"message":"INVALID_KEYS"}, status = 400)
  • 일반 회원 가입에 성공하면 회원가입 시 입력한 폰 번호로 가입 축하 sms를 보낸다.
  • 로그인에 성공하면 해당 유저의 id값을 토큰으로 반환한다.
  • kakao_login의 경우 처음으로 외부 API를 사용하여 어려움을 겪었다. 어떤 형식으로 데이터를 주고받는지 개념조차 잡히지 않아 처음에 많은 생각과 검색을 하였다. 하지만 공식 문서와 많은 블로그 글들을 읽으며 조금씩 이해가 되었으며, 지정해 준 주소로 카카오에서 원하는 키값을 보내주니 원하는 정보를 얻을 수 있었다.
  • 이번 기회로 RESTful API에 대해 약간 알게 된 것 같아 시간이 된다면 다른 RESTful API도 사용해보고 싶다.

0개의 댓글