""" Django settings for nhn_prj project. """ from pathlib import Path from datetime import timedelta from dotenv import load_dotenv import os import sys # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent load_dotenv(dotenv_path=os.path.join(BASE_DIR, ".env.dev")) # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = os.environ.get( "SECRET_KEY", "django-insecure-default-key-change-in-production" ) # SECURITY WARNING: don't run with debug turned on in production! DEBUG = int(os.environ.get("DEBUG", default=1)) ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "rest_framework", "rest_framework_simplejwt", "drf_yasg", "corsheaders", "nhn", ] MIDDLEWARE = [ "nhn_prj.middleware.RequestLoggingMiddleware", # 요청 로깅 (맨 위) "corsheaders.middleware.CorsMiddleware", "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", ] ROOT_URLCONF = "nhn_prj.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] WSGI_APPLICATION = "nhn_prj.wsgi.application" # Database if os.environ.get("SQL_ENGINE"): DATABASES = { "default": { "ENGINE": os.environ.get("SQL_ENGINE", "django.db.backends.sqlite3"), "NAME": os.environ.get("SQL_DATABASE", BASE_DIR / "db.sqlite3"), "USER": os.environ.get("SQL_USER", "user"), "PASSWORD": os.environ.get("SQL_PASSWORD", "password"), "HOST": os.environ.get("SQL_HOST", "localhost"), "PORT": os.environ.get("SQL_PORT", "3306"), } } else: DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": BASE_DIR / "db.sqlite3", } } # Password validation AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # Internationalization LANGUAGE_CODE = "ko-kr" TIME_ZONE = "Asia/Seoul" USE_I18N = True USE_TZ = True # Static files (CSS, JavaScript, Images) STATIC_URL = "static/" # Default primary key field type DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" # CORS settings CORS_ALLOWED_ORIGINS = [ "http://localhost:3000", "http://127.0.0.1:3000", "http://192.168.0.100:3000", "https://demo.test", "http://demo.test", "https://www.demo.test", "https://sample.test", "http://sample.test", "https://www.sample.test", "http://www.sample.test", "https://auth.sample.test", "http://auth.sample.test", "https://blog.sample.test", "http://blog.sample.test", "https://www.icurfer.com", "https://icurfer.com", ] # 개발 환경에서 모든 origin 허용 (필요시) CORS_ALLOW_ALL_ORIGINS = bool(DEBUG) CORS_ALLOW_CREDENTIALS = True # 커스텀 헤더 허용 (X-NHN-Token, X-NHN-Region 등) CORS_ALLOW_HEADERS = [ "accept", "accept-encoding", "authorization", "content-type", "dnt", "origin", "user-agent", "x-csrftoken", "x-requested-with", # NHN Cloud 커스텀 헤더 "x-nhn-token", "x-nhn-region", "x-nhn-tenant-id", "x-nhn-storage-account", "x-nhn-appkey", ] # REST Framework settings REST_FRAMEWORK = { "DEFAULT_AUTHENTICATION_CLASSES": [ "nhn.authentication.StatelessJWTAuthentication", ], "DEFAULT_PERMISSION_CLASSES": [ "rest_framework.permissions.AllowAny", ], } # JWT settings ISTIO_JWT = int(os.environ.get("ISTIO_JWT", default=0)) if ISTIO_JWT: # RS256 for Istio SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(minutes=30), "REFRESH_TOKEN_LIFETIME": timedelta(days=1), "ALGORITHM": "RS256", "SIGNING_KEY": open(os.path.join(BASE_DIR, "keys/private.pem")).read(), "VERIFYING_KEY": open(os.path.join(BASE_DIR, "keys/public.pem")).read(), "AUTH_HEADER_TYPES": ("Bearer",), "USER_ID_FIELD": "name", "USER_ID_CLAIM": "name", } else: # HS256 default SIMPLE_JWT = { "ACCESS_TOKEN_LIFETIME": timedelta(minutes=30), "REFRESH_TOKEN_LIFETIME": timedelta(days=1), "ALGORITHM": "HS256", "SIGNING_KEY": SECRET_KEY, "AUTH_HEADER_TYPES": ("Bearer",), "USER_ID_FIELD": "name", "USER_ID_CLAIM": "name", } # Auth server URL AUTH_VERIFY_URL = os.environ.get("AUTH_VERIFY_URL", "") # Logging LOGGING = { "version": 1, "disable_existing_loggers": False, "formatters": { "verbose": { "format": "[{asctime}] {levelname} {name} {message}", "style": "{", }, }, "handlers": { "console": { "class": "logging.StreamHandler", "formatter": "verbose", "stream": sys.stdout, }, }, "root": { "handlers": ["console"], "level": "INFO", }, "loggers": { "django": { "handlers": ["console"], "level": "INFO", "propagate": False, }, "django.request": { "handlers": ["console"], "level": "INFO", # ERROR -> INFO로 변경하여 모든 요청 로깅 "propagate": False, }, # NHN 앱 로거 명시적 설정 "nhn": { "handlers": ["console"], "level": "INFO", "propagate": False, }, "nhn.packages": { "handlers": ["console"], "level": "INFO", "propagate": False, }, # 요청 로깅 미들웨어 "nhn_prj.middleware": { "handlers": ["console"], "level": "INFO", "propagate": False, }, }, }