laravellaravel-8laravel-artisanlaravel-storagelaravel-filesystem

Symbolic link from public/storage to storage/app/public still makes the files in the storage directory accessible from the web


What I have done

When I researched about storing files in laravel. I came across two approaches.

  1. Storing the assets directly inside the public folder.
  2. Creating a symbolic link from public/storage to storage/app/public

When I researched about which one two use, I came across this stack overflow link. ๐Ÿ‘‰ Difference between storing files in public directory and in storage in Laravel 5.4 In this link in the top answer it was mentioned,

Public folder means files will be publicly accessible.

For example an image stored in public/images/my-image.jpegcan be viewed by anyone by going to mysite.com/images/my-image.jpeg

However, files stored in storage directory are only available to your app.

๐Ÿ‘† Since, including in the mentioned stack overflow post above, and many other posts I have read on different platforms implied the fact that files in the public directory are web accessible whereas the files inside the storage directory are not, I tried to test this by storing files both in the public directory and in the storage directory one at a time, and then checking if the files are accessible through the web url.
My attempts went as below,

  1. First I added the path images/ in the public directory and placed some images (Let us say test1.jpg, test2.jpg and test3.jpg) into that directory. Then inside my blade template for the src attribute of my img tags I referred to them as URL('images/test1.jpg') etc... and they were indeed rendered on the webpage. Then I also tried to access the images from the url by going to http://localhost:8000/images/test.jpg. The result was as expected, The images were rendered on the web page + they were accessible from the url
  2. Then I ran the command php artisan storage:link on the console, which according to the articles I read, should create a symbolic link between the directories public/storage and storage/app/public. As soon as I ran the command, I got a new folder called storage created in the public directory. Then I moved all my images to that public/storage directory. Then set the src attribute my img tags as URL('storage/test1.img') etc... the images were rendered on the web page. Then I tried to check if the images are still accessible from the url. for that on the url bar I went to http://localhost:8000/storage/test1.jpg. The images were STILL ACCESSIBLE from the url.

Problem

However, according to the answer I have mentioned and some other similar links, I expected those images to not be accessible from the url in the 2) above since the images should now be actually in the storage/app/public which we have created a symbolic link to from public/storage. (Files inside the storage directory should not be publicly accessible right?)

This led me to two questions,

  1. Why are the images are still being accessible from the url even after I created a symbolic link from public/storage to storage/app/public and stored the images in the public/storage directory?
  2. As happened with my case, if the files in the public/storage are still accessible through the web url, what are the advantages of actually creating the symbolic link? It does not seem to offer any more security since the files are still accessible from the url.

It would be really helpful if anyone can help me understand the answers to the above two questions I have. Thanks.


Solution

  • What's happening to you is the expected behavior.

    The purpose of Laravel storage is to interact with your local files and make use of Laravel helpers, besides being easily shared across deployments. Saying that I would avoid moving your files directly to your public folder.

    On the other hand, by adding files to your storage/app/public folder you are assuming that those files will be publicly accessible, but they won't be until you create a symbolic link which is a special kind of file that points to another file. When you create a symbolic link you are saying "hey, if the user reaches http://localhost:8000/storage/ just show the files stored in storage/app/public"

    So if you want private files (and you have created a symbolic link) just don't upload them to your storage/app/public folder, instead of that put your private files out from the public folder such as storage/app/myfiles

    He are your answers:

    1 - Why are the images are still being accessible from the url even after I created a symbolic link from public/storage to storage/app/public and stored the images in the public/storage directory?

    Because in fact, you have created a symbolic link for that purpose, making the storage/app/public publicly accessible.

    2 - As happened with my case, if the files in the public/storage are still accessible through the web url, what are the advantages of actually creating the symbolic link? It does not seem to offer any more security since the files are still accessible from the url.

    As said, the advantage is to make use of Laravel filesystem. The public link doesn't determine the privacy of your files