وبلاگ نت‌آرامآموزش، تجربه و راهکارهای زیرساخت

تصویر آپلودشده Django خطای 403 می‌دهد؛ مسیر و دسترسی media را درست کنیم

تشخیص علت 403 تصاویر آپلودشده جنگو و تنظیم امن مسیر و دسترسی فایل‌های media.

انتشار:
توسط تیم فنی نت‌آرام
۶ دقیقه زمان مطالعه
۰ دیدگاه
محتوای تخصصی، ساده و کاربردی
هماهنگ با هویت حرفه‌ای نت‌آرام
بازگشت به لیست مقالات
تصویر شاخص مقاله تصویر آپلودشده Django خطای 403 می‌دهد؛ مسیر و دسترسی media را درست کنیم در وبلاگ نت‌آرام
محتوای آموزشی وبلاگ نت‌آرام
تصویر را از پنل Django آپلود کرده‌اید، اما در سایت باز نمی‌شود و درخواست آن 403 Forbidden برمی‌گرداند. فایل ممکن است در مسیر درست نباشد، وب‌سرور اجازه خواندن یا عبور از یکی از پوشه‌ها را نداشته باشد، یا خود برنامه و سیاست دسترسی عمداً آن را محدود کرده باشند. فایل‌های آپلودی با فایل‌های static پروژه یکسان نیستند.
اول مشخص کنید تصویر باید عمومی باشد یا خصوصی. اگر سند مشتری، فایل شخصی یا محتوای نیازمند ورود است، عمومی‌کردن پوشه برای حذف ۴۰۳ راه‌حل امنی نیست؛ باید دسترسی همان کاربر در برنامه کنترل شود.

۱. درخواست ناموفق و پاسخ را پیدا کنید

در مرورگر F12 را باز کنید و در زبانه Network روی درخواست تصویر کلیک کنید. نشانی، وضعیت و پاسخ را ببینید. 404 معمولاً یعنی فایل یا مسیر پیدا نشده و 403 یعنی درخواست در یکی از لایه‌ها رد شده است؛ صفحات خطای سفارشی می‌توانند جزئیات را پنهان کنند. یک فایل آزمایشی غیرحساس بارگذاری کنید و نشانی آن را در پنجره ناشناس امتحان کنید.
اگر فایل فقط پس از ورود باید دیده شود، رفتار پنجره ناشناس می‌تواند طبیعی باشد. اگر تصویر عمومی است ولی فقط بعضی شبکه‌ها ۴۰۳ می‌گیرند، هات‌لینک، CDN و قوانین دسترسی را نیز در همان زمان بررسی کنید.

۲. تنظیم media و محل ذخیره را بشناسید

در پوشه پروژه و محیط مجازی درست، در فایل تنظیمات، مقدار MEDIA_URL و MEDIA_ROOT یا تنظیم storage پروژه را ببینید. MEDIA_URL نشانی عمومی است؛ MEDIA_ROOT مسیر ذخیره محلی را مشخص می‌کند. در پروژه‌ای که از storage ابری استفاده می‌کند، فایل ممکن است اصلاً روی دیسک محلی هاست نباشد.
برای تنظیمات ساده Django می‌توانید در محیط پروژه از دستور زیر استفاده کنید:
کد / دستورpython manage.py shell -c "from django.conf import settings; print('MEDIA_URL:', settings.MEDIA_URL); print('MEDIA_ROOT:', settings.MEDIA_ROOT); print('storage backend:', getattr(settings, 'STORAGES', {}).get('default', {}).get('BACKEND', 'check project settings'))"
این فرمان فقط نام backend پیش‌فرض را نشان می‌دهد و گزینه‌های storage را چاپ نمی‌کند؛ گزینه‌ها ممکن است اطلاعات محرمانه داشته باشند. تنظیم STORAGES از Django 4.2 وجود دارد. اگر در نسخه قدیمی‌تر عبارت check project settings را دیدید، تنظیم DEFAULT_FILE_STORAGE را در فایل تنظیمات پروژه بررسی کنید. خروجی ممکن است مسیر داخلی را نشان دهد؛ آن را بدون حذف اطلاعات حساس عمومی نکنید. مطمئن شوید فرمان با همان تنظیمات و محیطی اجرا شده که برنامه وب استفاده می‌کند.

۳. وجود فایل و دسترسی مسیر را بررسی کنید

اگر storage محلی است، مسیر واقعی فایل آزمایشی را با مقدار تنظیمات تطبیق دهید:
کد / دستورls -ld /path/to/media ls -l /path/to/media/example.jpg namei -l /path/to/media/example.jpg
مسیرها نمونه‌اند و باید با مسیر واقعی جایگزین شوند. namei در برخی سیستم‌ها موجود نیست؛ این ابزار مجوز هر بخش مسیر را نشان می‌دهد. خواندن فایل کافی نیست: پردازش تحویل‌دهنده باید بتواند از پوشه‌های والد نیز عبور کند. نام کاربر وب‌سرور یا سرویس و مجوزهای واقعی را از مدیر سرویس بگیرید.

اصلاح مجوز یک تصویر عمومی آزمایشی

این نمونه فقط برای یک تصویر عمومی و پوشه‌ای است که تمام محتوای آن عمداً عمومی است. مجوزهای زیر به کاربران دیگر سیستم نیز اجازه خواندن می‌دهند؛ برای سند مشتری، پوشه مشترک با فایل‌های خصوصی یا مسیر والد حساب از آن‌ها استفاده نکنید. ابتدا مسیر واقعی را با خروجی بخش قبل جایگزین و مقدار فعلی را ثبت کنید:
کد / دستورstat -c '%A %a %U:%G %n' /srv/myapp/media /srv/myapp/media/example.jpg
برای مثال، اگر پوشه عمومی مجوز عبور ندارد و تصویر عمومی نیز برای وب‌سرور خواندنی نیست، مالک همان فایل‌ها می‌تواند فقط روی همین دو مسیر اجرا کند:
کد / دستورchmod 755 /srv/myapp/media chmod 644 /srv/myapp/media/example.jpg stat -c '%A %a %U:%G %n' /srv/myapp/media /srv/myapp/media/example.jpg
دستور اول خواندن و عبور از پوشه عمومی را مجاز می‌کند و دستور دوم اجازه خواندن تصویر عمومی را می‌دهد، بدون اینکه به دیگران حق نوشتن بدهد. خروجی آخر باید به‌ترتیب 755 و 644 را نشان دهد. این دستورها زیرپوشه‌ها و مسیرهای والد را تغییر نمی‌دهند؛ اگر namei نشان می‌دهد یک پوشه والد دسترسی لازم را ندارد، ابتدا از عمومی‌بودن و سیاست دسترسی آن مطمئن شوید. در هاست اشتراکی، اگر مالک فایل نیستید یا تغییر مجوز رد شد، مسیر و خطای دقیق را به پشتیبانی بدهید؛ دستور را با دسترسی ریشه اجرا نکنید.
اگر نتیجه نامناسب بود، فقط برای همین مسیرها عددهای ثبت‌شده در خروجی اول را جایگزین و با chmod برگردانید؛ مثلاً اگر مجوز قبلی تصویر واقعاً 640 بود، chmod 640 /srv/myapp/media/example.jpg آن را برمی‌گرداند. مقدار نمونه را بدون مشاهده مجوز قبلی کپی نکنید. از chmod -R 777 و عمومی‌کردن فایل خصوصی برای رفع عجولانه خطا خودداری کنید.

۴. وب‌سرور و تنظیمات سرویس را تطبیق دهید

در تولید، فایل‌های media معمولاً با وب‌سرور یا storage مناسب تحویل می‌شوند؛ قابلیت ساده فایل‌دهی سرور توسعه Django راهکار عمومی تولید نیست. در سرور مستقل اگر Nginx رسانه عمومی را سرو می‌کند، مسیر location باید به پوشه درست اشاره کند. یک مثال مفهومی:
کد / دستورlocation /media/ { alias /srv/myapp/media/; }
این مسیر نمونه است و نباید بدون تطبیق با پیکربندی موجود کپی شود. فایل باید واقعاً زیر همان پوشه باشد، وب‌سرور مجوز لازم داشته باشد و قوانین دیگر درخواست را رد نکنند. فایل‌های بارگذاری‌شده کاربر قابل اعتماد نیستند؛ وب‌سرور نباید آن‌ها را به‌عنوان کد اجرا کند. برای کاهش خطر، درباره تحویل رسانه کاربران از دامنه جداگانه و تنظیم‌های امنیتی مطابق راهنمای Django تصمیم بگیرید.
در هاست اشتراکی ممکن است امکان ویرایش تنظیم Nginx وجود نداشته باشد. مسیر، نام فایل آزمایشی، زمان و خروجی بدون رمز را به پشتیبانی بدهید. در سرور مستقل، ابتدا با sudo nginx -T بخش server مربوط به دامنه و فایل تنظیمی آن را پیدا کنید؛ خروجی کامل ممکن است اطلاعات داخلی داشته باشد. از همان فایل یک نسخه پشتیبان در محل امن بگیرید و نمونه location را پس از تطبیق مسیر، داخل همان بخش قرار دهید. سپس اجرا کنید:
کد / دستورsudo nginx -t && sudo systemctl reload nginx && sudo systemctl status nginx --no-pager
علامت && باعث می‌شود reload فقط در صورت موفقیت آزمون انجام شود و وضعیت نیز پس از reload موفق نمایش داده شود. اگر آزمون خطا داد، همان فایل پشتیبان را برگردانید و دوباره nginx -t را اجرا کنید؛ تنظیم معیوب را reload نکنید. دستورهای systemctl برای سرور دارای systemd هستند. در غیر این صورت روش reload نصب خودتان را به‌کار ببرید.

۵. نتیجه را با فایل جدید و قدیمی بسنجید

یک تصویر عمومی بی‌اهمیت تازه آپلود و همان لینک را در مرورگر ناشناس باز کنید. سپس یک تصویر قدیمی را امتحان کنید؛ تفاوت می‌تواند به مجوزهای ساخت فایل یا مسیر ذخیره مربوط باشد. اگر فایل خصوصی است، علاوه بر کاربر مجاز، دسترسی کاربر ناشناس و کاربر دیگر را هم امتحان کنید.
برای فایل‌های CSS و JavaScript پروژه، راهنمای static جنگو را بخوانید. اطلاعات هاست پایتون نت‌آرام و نکات استقرار Django در دسترس است.
اشتراک‌گذاری:
لینکدینتلگرامایکس

دیدگاه‌ها (۰)

دیدگاه‌های تاییدشده و پاسخ‌های تیم نت‌آرام