محمد رضا
3 سال پیش توسط محمد رضا مطرح شد
3 پاسخ

تفاوت storage.app.public و پوشه ی public لاراول بعد از storage:link

سلام دوستان
در رابطه با قرار دادن فایل در بخش های مختلف لاراول داشتم بررسی میکردم توضیحات ارزنده ی دوست خوبمون @mhyeganeh رو توی این گفتو گو دیدم و سوالی برام پیش اومد.

ما اگر بخواییم فایلی در دسترس عموم باشه توی پوشه ی public (واقع در روت اصلی ) قرار میدیم
و اگر بخواییم غیر قابل دسترس و دانلودی و امن باشه داخل storage قرار میدیم
حالا اگر بیاییم storage رو لینک کنیم که پابلیک بشه و در دسترس عموم قرار بگیره چه مزیتی یا تفاوتی با پوشه public روت اصلی داره؟
وقتی هر دو پابلیک هستن؟؟
اگر بخواییم اواتار یا عکس هر فرد فقط خودش ببینه و بشه لینک کردش توی صفحه اما کس دیگه ای با تعییر ادرس اون اواتار یا هرچی نتونه بهش دسترسی پیدا کنه میشه؟
حس میکنم فقط ب خاطر بخش بندی کردن معنایی بهتر اواتار رو میزارن توی storage/public و link میکننش تا عمومی بشه وگرنه فرقش چیه؟


ثبت پرسش جدید
محمدحسن یگانه
تخصص : Full-Stack Web Developer Freel...
@mhyeganeh 3 سال پیش آپدیت شد
4

سلام

ممنون از لطفتون. در حد توان مواردی که بلدم رو خدمتتون عرض می‌کنم:

اینکه گفتید:

ما اگر بخواییم فایلی در دسترس عموم باشه توی پوشه ی public (واقع در روت اصلی ) قرار میدیم
و اگر بخواییم غیر قابل دسترس و دانلودی و امن باشه داخل storage قرار میدیم.

شاید به این شکل خیلی درست نباشه. توضیحاتی هم عرض می‌کنم تقریبا هیچ کدوم اجباری نیستند و بیشتر جنبه Best Practice دارند:

پوشه public در مسیر روت اصلی رو اینطور در نظر بگیرید که تمام asset های وبسایت که توسط توسعه دهنده در بخش‌های مختلف مورد استفاده قرار گرفته‌اند قرار می‌گیرند. مثلا فایل های css و js و فایل فونت ها و احیانا متعلقات پکیج‌ها و آن دسته از تصاویر و فیلم‌هایی که جزوی از قالب وبسایتتون هستند. مثلا تصویر بنر معرفی و لوگو و آیکون‌ها و مواردی از این جنس وتمام.

اما هر آن چیزی که عمدتا کاربران از طریق پنل قرار هست آپلود کنندد بهتر است در Storage ذخیره شوند. چه میخواد تصویر محصولات و وبلاگ و ... باشه که توسط ادمین آپلود می‌شوند و چه فایل پیوست درخواست و تصویر آواتار و ... که توسط کاربران عادی قرار هست آپلود بشن. یک راه تشخیص دیگه برای انتخاب بین storage و پوشه public در روت اصلی این هست که مثلا آیا این مورد خاص باید در نسخه Remote Repostitory هم Push بشه یا نه. اگر آره میره داخل public و اگر نه sotorage. طبیعتا مواردی که مربوط به ظاهر قالب هستند و عمدتا هم بصورت ثابت نمایش داده می‌شوند باید به VCS تون اضافه بشن. ولی احتمالا لزومی نداره و منطقی نیست تصویر آواتار کاربران یا فایل‌های پیوست تیکت‌ها رو هم اضافه کنید.

یکی دیگه از مزیت‌های Sotrage هم متدها و helper های خیلی کاربردی و متنوعی هست که برای Storage Facade تعبیه شده و کارتون رو برای آپلود و کلا کار کردن با فایل‌ها خیلی راحت‌ می‌کنه و حیفه ازش محروم بمونیم.

این تا اینجای کار.

حالا یک بحث کاملا جداگانه دیگه ای داریم بنام سطح دسترسی عمومی به یک فایل. به طور کلی هر فایلی که در public روت اصلی قرار بگیره بصورت مستقیم قابل دسترسی هست و هیچ کنترلی از طریق لاراول نمی‌تونید داشته باشید. چون اصلا این قضیه در خود وب سرور و قبل از رسیدن درخواست به لاراول هندل میشه.

اما داخل پوشه storage ما دو تا فضا داریم. یکی /storage و دیگری sotorage/public. و فرقشون هم اینه که اگر فایلی داخل storage/public قرار گرفت دوباره مثل همون حالت قبل هست و با URL مستقیم قابل دسترس هستند. این عملیات هم مربوط میشه به همون ماجرای storage:link که میاد یک symbolic link از این پوشه اضافه میکنه به همون پوشه public روت اصلی. به همین خاطر شما می‌تونید مثل آدرس زیر به محتوای اون دسترسی داشته باشید:

<img src="/storage/avatar/ali.jpg>

اما فایل‌هایی که خارج از این پوشه قرار می‌گیرند، دیگه امکان دسترسی مستقیم ندارند. به همین خاطر درخواست پیشروی می‌کنه و به لاراول میرسه و از طریق route به کنترلتون میرسه. حالا اونجا می‌تونید انواع اعتبارسنجی ها و عملیات ها رو انجام بدید و اگر همه چیز اوکی بود، اون وقت با استفاده از متدهای Storage فایل رو به کاربر برسونید یا مثلا مثل زیر:

return response()->download('paht_to_file');

اما نکته آخر اینکه تا جایی که بنده می‌دونم این قضیه اعمال محدودیت سطح دسترسی رو صرفا در خصوص مواردی میشه اعمال کرد که قصد دانلود مستقیم فایل رو داشته باشیم یا مثلا stream کردن فیلم و ...
ولی اگر اون فایل باید توسط مرورگر لود بشه (مثل فایل css و js و حتی تصاویر و media هایی که قرار هست داخل وب پیج استفاده بشن و یا به نمایش دربیان) باید حتما حتما امکان دسترسی مستقیم به فایل وجود داشته باشه و راه گریز ساده‌ای وجود نداره. یک راه سختش مثلا این هست که فایل رو در بک‌اند به کد Base64 تبدیل کنیم و به جای آدرس دهی مسقیم به خود فایل به این شکل نمایش بدیم:

<img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==">

که خوب شاید معایب زیادی مخصوصا از جهت بهره‌وری داشته باشه. پس با این اوصاف تصویر آواتار کاربران رو به سادگی نمیشه محدود کرد که فقط مثلا هر کاربر به تصویر خودش دسترسی داشته باشه و حتما باید داخل storage/public یا public در روت اصلی قرار بگیرند. باز هم اگر این قضیه براتون خیلی مهمه یک روش رایج دیگه این هست که نام گذاری این فایل ها رو بصورت عباراتی رندوم و غیرقابل حدس قرار بدید و داخل دیتابیس ذخیره کنید. اینجوری تا کسی ندونه اسم فایل آواتار بقیه چیه عملا نمی‌تونه بهش برسه و دغدغه تا حد زیادی برطرف میشه.

موفق و پیروز باشید.


علی بیات
تخصص : توسعه دهنده ارشد وب
@ali.bayat 3 سال پیش مطرح شد
1

درود

قرار دادن فایلهایی که آپلود میکنیم، به صورت مستقیم در پوشه public کار زیاد جالبی نیست.. مشکل از جایی شروع میشه که می‌خواهیم دسترسی فایل ها رو محدود کنیم..
لاراول برای رفع این مشکل اومده و از یک file storage سیستم قدرتمند استفاده کرده

لاراول برای کارکردن با فایلهای از پکیج معروف Flysystem استفاده میکنه..
از منظر لاراول هر فضایی که میشه فایل های کاربر در اون قرار بگیره، یک دیسک نام داره..
اگر به فایل filesystems.php در پوشه config مراجعه کنی
میبینی که دیسک های local و public به شکل پیش فرض تعریف شدند.
دیسک public از طریق مرورگر در دسترس هست اما دیسک local خیر...
به این ترتیب راهی برای عدم دسترسی عمومی به بعضی دیسک ها داریم
و در نهایت با اجرای storage:link یه سری symlink به فولدرهای مجاز میسازیم و تمام.

ممکنه روند بالا کمی الکی پیچیده به نظر برسه اما نکته اش در اینه که استفاده از این سیستم فواید زیر رو در بر داره:

  • به راحتی فایل ها رو سازماندهی میکنیم
  • به راحتی میتونیم url های معمولی و signed شده بسازیم
  • برای ذخیره آدرس ها در دیتابیس کارمون خیلی راحت تره
  • این سیستم با کلاس Request لاراول کاملا تعامل داره و پروسه آپلود رو روی یک دیسک خاص آسون میکنه.
  • میشه برای کاربران خاص لینک دانلودی ساخت که در فضای Public پروژه موجود نیست
  • ...

در کنار این موارد حتی میتونی دیسک های خودت رو بسازی
و حتی بهتر از اون اینکه لاراول از دیسک ابری S3 هم پشتیبانی میکنه.. که برای پروژه هایی که به فضای ذخیره سازی بالا نیاز دارند، حیاتیه. این باعث میشه بتونی از سرویس هایی مثل AWS S3, DigitalOcean, Poshtiban استفاده کنی


محمد رضا
تخصص : Full Stack Developer
@salar.mohammad2013 3 سال پیش مطرح شد
0

@mhyeganeh
@ali.bayat
سپاس از هر دو دوست بزرگوار
بسیار آموزنده و عالی و لایق انتخاب بهترین پاسخ 👌👍


برای ارسال پاسخ لازم است وارد شده یا ثبت‌نام کنید

ورود یا ثبت‌نام