[Westagram] 회원가입, 로그인 엔드포인트

Nina·2020년 10월 10일
0

Westagram

목록 보기
1/2
post-thumbnail

1. Project와 App 생성

2. 초기 세팅(settings.py)

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
#    'django.contrib.admin',
#    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'corsheaders',
    'user',
    'posting',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
#    'django.middleware.csrf.CsrfViewMiddleware',
#    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'corsheaders.middleware.CorsMiddleware',
]


# Database
# https://docs.djangoproject.com/en/3.1/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'westagram',
        'USER': 'root',
        'PASSWORD': '',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}



# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'Asia/Seoul'

USE_I18N = True

USE_L10N = True

USE_TZ = True


##CORS
CORS_ORIGIN_ALLOW_ALL=True
CORS_ALLOW_CREDENTIALS = True

CORS_ALLOW_METHODS = (
    'DELETE',
    'GET',
    'OPTIONS',
    'PATCH',
    'POST',
    'PUT',
)

CORS_ALLOW_HEADERS = (
    'accept',
    'accept-encoding',
    'authorization',
    'content-type',
    'dnt',
    'origin',
    'user-agent',
    'x-csrftoken',
    'x-requested-with',
)

3. models.py

from django.db import models

# Create your models here.
class User(models.Model):
    mobile      = models.CharField(max_length=200, unique=True, null=True)
    email       = models.EmailField(max_length=200, unique=True)
    full_name   = models.CharField(max_length=45)
    username    = models.CharField(max_length=45, unique=True)
    password    = models.CharField(max_length=300)

    def __str__(self):
        return self.username
    
    class Meta():
        db_table = 'users'

유저 DB에 저장되는 정보들.

4. views.py

import json

from django.http import JsonResponse
from django.views import View
from user.models import User

# Create your views here.

class SignupView(View):

    def post(self, request):
        try:
            data = json.loads(request.body)
            if ('@' not in data['email'] or 
                '.' not in data['email']):
                return JsonResponse(
                    {'MESSAGE': 'Invalid Email'},
                    status=403)
            elif len(data['password']) < 8:
                return JsonResponse(
                    {'MESSEAGE': 'The password length should be greater than 7.'},
                    status=400)
            elif (User.objects.filter(email = data['email']).exists() or 
                User.objects.filter(username = data['username']).exists()):
                return JsonResponse(
                    {'MESSAGE': 'The given information has been already taken.'},
                    status=403)
            else:
                User(
                    mobile      = data['mobile'],
                    email       = data['email'],
                    full_name   = data['full_name'],
                    username    = data['username'],
                    password    = data['password'],
                    follow      = data['follow']
                ).save()
                return JsonResponse(
                    {'MESSAGE':'REGISTER_SUCCESS'}
                    , status=201)

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

class LoginView(View):
    
    def post(self, request):
        try:
            data = json.loads(request.body)
            if 'email' in data.keys():
                if User.objects.filter(email = data['email']).exists():
                    if User.objects.get(email = data['email']).password == data['password']:
                        return JsonResponse({'MESSAGE':'SUCCESS'}, status=200)
                    else:
                        return JsonResponse({'MESSAGE':'INVALID_USER'},status=401)
                else:
                    return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)
            elif 'mobile' in data.keys():
                if User.objects.filter(mobile = data['mobile']).exists():
                    if User.objects.get(mobile = data['mobile']).password == data['password']:
                        return JsonResponse({'MESSAGE':'SUCCESS'}, status=200)
                    else:
                        return JsonResponse({'MESSAGE':'INVALID_USER'},status=401)
                else:
                    return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)
            elif 'username' in data.keys():
                if User.objects.filter(username = data['username']).exists():
                    if User.objects.get(username = data['username']).password == data['password']:
                        return JsonResponse({'MESSAGE':'SUCCESS'}, status=200)
                    else:
                        return JsonResponse({'MESSAGE':'INVALID_USER'},status=401)
                else:
                    return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)

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

(1) SignupView(회원가입)

먼저 try-except를 통해 키 값이 주어지지 않으면 에러가 발생하게 하였다.
이메일 및 비밀번호의 형식이 지켜지지 않은 경우, 이메일이나 아이디(username)이 중복되는 경우에도 에러가 발생하게 하였고, 그렇지 않은 경우 데이터가 저장된다.

(2) LoginView(로그인)

회원가입과 마찬가지로 try-except를 이용해 키 값이 주어지지 않은 경우 에러가 발생하게 하였다. 로그인은 이메일, 핸드폰번호, 아이디 중 하나를 이용해서 하기 때문에 각각의 경우를 다 나누어서 코드를 작성하였는데, 확실히 중복이 많아 비효율적으로 보인다. 리팩토링 필요.

(리팩토링 후)

try:
            data            = json.loads(request.body)
            given_pw        = data['password'].encode('utf-8')
            accessing_user  = User.objects.get(Q(email = data['user_input']) | Q(mobile = data['user_input']) | Q(username = data['user_input']))
           
            sucess_msg      = JsonResponse({'MESSAGE':'SUCCESS',
                                            'AUTHORIZATION':jwt.encode({'id' : accessing_user.id}, 'SECRET', algorithm = 'HS256').decode()},
                                            status=200)
            password_msg    = JsonResponse({'MESSAGE':'INCORRECT PASSWORD'},status=401)

            if accessing_user:
                if bcrypt.checkpw( given_pw , accessing_user.password.encode('utf-8') ):
                    return sucess_msg
                else:
                    return password_msg

            else:
                return JsonResponse({'MESSAGE':'INVALID_USER'}, status=401)

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

5. project_westagram/urls.py

from django.urls import path
from user.views import SignupView, LoginView

urlpatterns = [
    path('user/signup', SignupView.as_view()),
    path('user/login', LoginView.as_view()),
]

6. 결과

(1) 회원가입

(2) 로그인

(3) 로그인(잘못된 패스워드 입력)

profile
https://dev.to/ninahwang

0개의 댓글