Luciano Braga
Luciano Braga

Reputation: 273

How to secure Laravel Storage folders

In my project, I have implemented auth and ACL for my controllers and routes. I have a file upload system accessible only if the user is logged. It's work fine.

My problem is on the uploaded files. The user can access any file if have a file URL. How I can implement auth on uploaded files?

I tried with routes, but when accessing my file through the browser the file is shown as if not have a route intercepting this URL.

I have used this code:

Route::get('/storage/document/3/4a15c1ab060be8f35.png', function () {
  return 'ok';
});

How can I implement auth on specific folders on storage? Thanks!

Upvotes: 8

Views: 18439

Answers (2)

Abdelsalam Shahlol
Abdelsalam Shahlol

Reputation: 1769

You can refer to my answer here. The process includes creating a new Storage Disk that saves files on /storage/app/ (not in public folder) and validating the request before serving the file to the user.

Upvotes: 4

Stephen Lake
Stephen Lake

Reputation: 1620

If you want to restrict access to files per user based on some sort of permission, you'll need to build that permission logic yourself (StackOverflow isn't going to do your job for you), but for the sake of answering this question, let's assume you already have that permission system in place and in order to check whether the user has access, our function is hasAccessToFile which basically just does a look up based on whatever your business logic requires.

Instead of serving all files publicly, you can serve individual files, here's a very brief example:

Route::get('files/{pathToFile}', function($pathToFile) {

    if (auth()->user()->hasAccessToFile($pathToFile)) {
        return response()->file($pathToFile);
    } else {
        return 'Nope, sorry bro, access denied!';
    }

});

See the File Responses documentation.

If you need to provide downloads of the files rather than serving of them, similarly:

Route::get('files/{pathToFile}', function($pathToFile) {

    if (auth()->user()->hasAccessToFile($pathToFile)) {
        return response()->download($pathToFile);
    } else {
        return 'Nope, sorry bro, access denied!';
    }

});

See the File Downloads documentation.

Upvotes: 14

Related Questions