Save my data

[DjangoREST + React] 1. 시작하기 본문

프로젝트/Python

[DjangoREST + React] 1. 시작하기

양을 좋아하는 문씨 2023. 5. 31. 10:55

DRF를 학습하기에 앞서 RESTApi가 무엇인지 알 필요가 있다.


  • REST Api : REST를 기반으로 하는 Api서버
    • REST : Representational State Transfer의 약자
      • 자원의 이름으로 자원의 상태를 구분하여 주고받는것
      • 웹에 존재하는 모든 자원에 이름과 주소를 부여하여 활용한다.
      • 핵심 구성요소로서 자원(URI)이 있고, 그 자원에 대한 행위(method)가 있고, 행위에 대한 내용(Representational)이 있다.
      • HTTP method의 종류
        • GET
          • 단순히 자원을 가져오는데 사용된다.
        • POST
          • 새로운 자원을 추가할 때 사용된다.
        • PUT
          • 자원에 대한 변경이 있을 때 사용된다.
          • 자원이 없다면 자원을 추가할 수 있다.
        • DELETE
          • 자원을 삭제할 때 사용된다.
        • PATCH
          • 존재하는 자원을 변경할 때 사용된다.
          • 존재하지 않는 자원에 대한 변경사항은 PUT을 활용한다.
          • 환경에 따라 지원하지 않는 경우도 있다.
      • REST의 특징
        • Server-Client
          • 서버와 클라이언트 각각의 역할이 명확하게 구분된다.
        • Stateless
          • 상태 정보를 저장하지 않는다.
          • 쿠키나 세션에 대한 처리 없이 들어오는 요청에 대해서만 처리한다.
        • Cacheable
          • HTTP의 캐싱 기능을 적용할 수 있다.
        • Layered System
          • 다중 계층으로 구성될 수 있다.
        • Uniform Interface 
          • 인터페이스는 통일되어야 한다.
      • REST 설계 규칙
        • URI
          1. 모든 리소스는 자신만의 URI를 가지고 있어야 한다.
          2. 동사로 된 주소를 사용하지 않는다.
          3. 대문자를 사용하지 않는다.
          4. 마지막에 슬래시를 포함하지 않는다.
          5. 언더바 대신 하이픈을 사용한다.
          6. 자원에 대한 행위는 HTTP method로 표현하되 URI에는 어떤 행위를 하는지 알 수 있는 단어를 포함하지 않는다.

Django REST Framework : Django를 기반으로 하는 REST Api 서버를 만들기 위한 라이브러리

 

파이썬 장고에서는 djangorestframework라는 라이브러리를 통해 RESTApi 서버를 개발할 수 있다.

개발에 앞서 기본적인 설정을 해 두었다.

pip install black mysqlclient djangorestframework djangorestframework-jwt python-dotenv
  • black : 코드 포매터는 black을 사용하는게 익숙하다.
  • mysqlclient : 기본 db는 sqlite로 되어있고 이 프로젝트에서는 mysql 사용을 할 것이기 때문에 mysqlclient을 설치
  • djangorestframework : RESTApi 서버 개발을 위한 설치
  • djangorestframework-simplejwt : jwt를 통해 인증을 관리할 예정이다
  • python-dotenv : .env로 시크릿 키 등을 관리할 예정이다.
django-admin startproject config .

위 명령어로 프로젝트를 생성해주고,

python manage.py startapp accounts
python manage.py startapp todo

위 명령어로 앱을 생성했다.

 

이제 config 폴더의 settings.py로 가서 기본 설정을 해줘야 한다.

# django secret key 관리

import os
from dotenv import load_dotenv

load_dotenv()

SECRET_KEY = os.getenv("SECRET_KEY")
ALLOWED_HOSTS = [
    "127.0.0.1",
    "localhost",
]
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    # library
    "rest_framework",
    # apps
    "accounts",
    "todo",
]
# db 변경 sqlite >>> mysql
# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': BASE_DIR / 'db.sqlite3',
#     }
# }

DATABASES = {
    "default": {
        "ENGINE": "django.db.backends.mysql",
        "NAME": "db_todo",
        "USER": "user_todo",
        "PASSWORD": os.getenv("MYSQL_PASSWORD"),
        "PORT": "3306",
        "HOST": "localhost",
        "OPTIONS": {
            "charset": "utf8mb4",
        },
    }
}
# restframework


REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": (
    	# simpleJWT에서는 기본 인증클래스로 아래의 하나만 사용하는 것 같다.
        "rest_framework_simplejwt.authentication.JWTAuthentication",
        # "rest_framework.authentication.SessionAuthentication",
        # "rest_framework.authentication.BasicAuthentication",
    ),
}
# jwt

from datetime import timedelta

SIMPLE_JWT = {
    # 토큰 라이프사이클 관리
    "ACCESS_TOKEN_LIFETIME": timedelta(minutes=30),
    "REFRESH_TOKEN_LIFETIME": timedelta(days=14),
    
    # 액세스 토큰 발급할때마다 리프레시토큰 갱신 여부
    "ROTATE_REFRESH_TOKENS": False,
    
    # 기존 리프레시 토큰의 블랙리스트 추가 여부
    # 나중에 로그아웃 관련 보안처리를 위해 미리 True로 해두었다(구체적인 계획은 없음).
    "BLACKLIST_AFTER_ROTATION": True,
    
    # 마지막 로그인 시간 업데이트 여부
    "UPDATE_LAST_LOGIN": True,
    
    # 서명에 사용할 알고리즘
    "ALGORITHM": "HS256",
    
    # 서명에 사용할 비밀키
    "SIGNING_KEY": os.getenv("JWT_SECRET_KEY"),
    
    # 검증에 사용할 공개키 (기본값 공백)
    "VERIFYING_KEY": "",
    
    # 유저 id 필드 (기본 "id")
    # 이메일을 로그인 기본 아이디로 사용할 계획이다.
    # 설정을 바꾸지 않을 경우,
    # https://jwt.io/ 에서 디코딩했을때 이메일 주소가 안나오고 db에 저장되어있는 userId가 나온다.
    "USER_ID_FIELD": "email",
    
    # 유저 id 클레임 이름 (기본 "user_id")
    # 위의 id 필드에 대응되는 value로 email이 들어가게 설정
    "USER_ID_CLAIM": "email",
}
AUTH_USER_MODEL = "accounts.User"

config 하위의 urls.py

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
    path("api/v1/todo/", include("todo.urls")),
    path("api/v1/accounts/", include("accounts.urls")),
]

루트 경로에 .env 파일을 만들어서 중요한 값들을 관리한다.

 

SECRET_KEY = "" <= 장고 시크릿 키
JWT_SECRET_KEY = "" <= jwt 디코딩 시크릿 키 (https://djecrety.ir/ 에서 생성했다.)
MYSQL_PASSWORD = "" <= mysql db에 접근하기 위한 mysql user 패스워드
DEBUG = "True"

 

Comments