sadiss's avatar

User specified download link

I have a table which have following fields

id | post_id | sender | receiver | filename | created_at | updated_at

1 | 1 | 1 | 2 | file.jpg | date | date

files are store in

storage/sender/postid/file.jpg which means it is in storage_direcotry/1/1/file.jpg

what i want to create a download link which only allow receiver to download the file any other user or guest try to access the link will end up seeing 404 or any other error.

Please help

0 likes
10 replies
ejdelmonico's avatar

@sadiss Use an access token like in a password reset link. You can inspect that code and get an idea of what to do.

kfirba's avatar
kfirba
Best Answer
Level 50

@sadiss Hey.

You can make the request go through your app and determine whether the request is valid or not. What I would do is expose an endpoint to download files, maybe something like:

example.com/downloads/{hash}

Now you are going to associate any file in your database with some kind of a hash. You would then create a controller to respond to that URI and determine whether the user should have access to the file or not:

public function show($hash)
{
    // Perform the authorization
    abort_unless(optional(auth()->user())->canDownload($hash), 404);
    
    return response()->file($pathToFile);
}
sadiss's avatar

can peoploe access the files in storage direcotry by writing the path? like mywebsite.com/storage_path/filemae?

if yes then how can i protect them from un auth users?

kfirba's avatar

@sadiss The storage folder is an internal storage. Unless you symlink it to somewhere in your public directory, no one can access that folder directly. There is a public directory in the storage folder that you can symlink but if your files are directly under the storage path, no one should be able to access them directly.

sadiss's avatar

so its mean if someone knows directory name in storage folder the file name i mean he knows where the file is in storage folder he still cannot download it without the token?

kfirba's avatar

@sadiss As long as you don't symlink that folder to the public folder, then yea, no one can access that.

sadiss's avatar

As long as you don't symlink that folder to the public folder. Can you please explain this line so i can double check i didn't made this mistake.

kfirba's avatar

@sadiss There is a public folder in your application. Everything in that folder is basically user-accessible content. Say you have images/some-image.jpg file in the public folder, anyone could access that image by visiting: example.com/images/some-image.jpg.

As you noticed, the storage folder is not inside the public folder, hence no one should be able to access it directly. But sometimes we do want to make some content in that folder user-accessible. To do so, we create a symlink. What does that mean? A symlink is a nickname for any file that contains a reference to another file or directory. So say I create a symlink from public/some-symlink-name to storage/public when someone visits example.com/some-symlink-name, he will be presented with the contents of the storage/public directory. If we have a file in the path storage/public/my-image.jpg and symlink to that folder, the file will be accessible under example.com/some-symlink-name/my-image.jpg.

To create such symlink, you may do something like:

ln -s path/to/application/storage/public path/to/application/public/my-symlink-name

Laravel has a command: php artisan storage:link that creates a symlink automatically between your storage/public folder and the public/storage folders.

Well basically, if you don't know if you have a symlink, you probably don't have one. Otherwise, you can simply check that by going into your public directory and type: ls -la and see if the file type is l (symlink) instead of d (directory) or - (file).

sadiss's avatar

Thanks @kfirba i will mark it as best answer after testing it :-)

sadiss's avatar

basically I am allowing users to upload project files in that storage folder ( storage path/userid/file). I also allowed them to upload

jpg, php, gif, jpeg, zip ... is it a security risk allowing them to upload php file? if so how to make it un executable?

Please or to participate in this conversation.