open the API up to the frontend
سینیور خواست زودتر به فرانتاند وصل شویم تا از آنجا هم تست شود. اینها
سمتِ ما لازم بودند:
CORS با allowlist صریح (نه ALLOW_ALL): احرازِ هویتِ ما توکنِ Bearer در هدر
است، پس origin ناشناس نباید از مرورگرِ کاربر به API ما بزند.
CORS_ALLOW_CREDENTIALS عمداً خاموش میماند — کوکیای در کار نیست و روشن
کردنش فقط سطحِ حمله اضافه میکند. CorsMiddleware بالاتر از CommonMiddleware
گذاشته شد وگرنه ریدایرکتِ APPEND_SLASH و خطای ۴۰۰ هدرِ CORS نمیگیرند و در
مرورگر بهشکلِ خطای مبهمِ شبکه دیده میشوند.
PATCH /api/user/profile اضافه شد؛ تا پیش از این هیچ راهی برای ثبتِ نامِ
کاربر نبود. GET /api/home بدونِ پارامتر حالا پایهی ذخیرهشدهی کاربر را
برمیگرداند و POST /api/ai/ask فقط با lessonId کار میکند — هر دو برای
اینکه فرانت لازم نباشد پایه را خودش نگه دارد. questionCount به
lessons/{id}/intro اضافه شد.
docs/frontend/api.ts و README.md کلاینتِ تایپدار و راهنمای اتصالاند، از
روی OpenAPI واقعیِ همین سرویس تولید شدهاند.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -53,6 +53,33 @@ ALLOWED_HOSTS = [h for h in os.environ.get('DJANGO_ALLOWED_HOSTS', '').split(','
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = [o for o in os.environ.get('CSRF_TRUSTED_ORIGINS', '').split(',') if o]
|
||||
|
||||
# --- CORS -------------------------------------------------------------------
|
||||
# فرانتاند (Vite/React) از یک origin دیگر صدا میزند، پس بدونِ این هدرها مرورگر
|
||||
# هر درخواستِ /api/ را قبل از رسیدن به Django رد میکند.
|
||||
#
|
||||
# allowlist صریح است، نه CORS_ALLOW_ALL_ORIGINS: احرازِ هویتِ ما توکنِ Bearer در
|
||||
# هدر است، پس origin ناشناس نباید بتواند از مرورگرِ کاربر به API ما بزند.
|
||||
# CORS_ALLOW_CREDENTIALS هم عمداً خاموش میماند — کوکیای در کار نیست و روشن
|
||||
# کردنش فقط سطحِ حمله اضافه میکند.
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
o for o in os.environ.get('CORS_ALLOWED_ORIGINS', '').split(',') if o
|
||||
]
|
||||
if DEBUG and not CORS_ALLOWED_ORIGINS:
|
||||
# پورتهای پیشفرضِ Vite/CRA برای توسعهی محلی.
|
||||
CORS_ALLOWED_ORIGINS = [
|
||||
'http://localhost:3000', 'http://127.0.0.1:3000',
|
||||
'http://localhost:5173', 'http://127.0.0.1:5173',
|
||||
]
|
||||
CORS_ALLOW_CREDENTIALS = False
|
||||
# فقط مسیرهای API؛ /admin/ و فایلهای استاتیک لازم نیست از origin دیگر خوانده شوند.
|
||||
CORS_URLS_REGEX = r'^/api/.*$'
|
||||
# Idempotency-Key و X-Internal-Key هدرهای خودماناند و در فهرستِ پیشفرض نیستند.
|
||||
CORS_ALLOW_HEADERS = (
|
||||
'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt',
|
||||
'origin', 'user-agent', 'x-csrftoken', 'x-requested-with',
|
||||
'idempotency-key', 'x-internal-key',
|
||||
)
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
@@ -67,6 +94,7 @@ INSTALLED_APPS = [
|
||||
# 3rd party
|
||||
'rest_framework',
|
||||
'drf_spectacular',
|
||||
'corsheaders',
|
||||
|
||||
# Tadrisino apps (فاز اول - ۴ از ۱۱ اپ)
|
||||
'accounts',
|
||||
@@ -104,6 +132,10 @@ INSTALLED_APPS = [
|
||||
|
||||
MIDDLEWARE = [
|
||||
'django.middleware.security.SecurityMiddleware',
|
||||
# ⚠️ CorsMiddleware باید تا حدِ ممکن بالا و حتماً قبل از CommonMiddleware
|
||||
# باشد، وگرنه پاسخهایی که زودتر برمیگردند (ریدایرکتِ APPEND_SLASH، خطای
|
||||
# ۴۰۰) هدرِ CORS نمیگیرند و در مرورگر بهشکلِ خطای مبهمِ شبکه دیده میشوند.
|
||||
'corsheaders.middleware.CorsMiddleware',
|
||||
'whitenoise.middleware.WhiteNoiseMiddleware',
|
||||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||||
'django.middleware.common.CommonMiddleware',
|
||||
|
||||
Reference in New Issue
Block a user