user2551614
user2551614

Reputation: 31

Laravel - Restrict certain downloads using authentication

Lets say I want to make an application where users can upload private files to a laravel based website. I dont want to make their files available to public, but I want them to be able to download the files after they have logged in.

So I need to verify that they have logged in, and that they have the correct account ID to download a specific file. How can I create this restriction?

I have been looking around http://laravel.com/docs with no success, and with google search I was only able to obtain some vanilla PHP samples, but it seems messy to integrate into laravel, which way do you recommend me to do this?

I may be overcomplicating the situation in my head, perhaps I could make a table in database with account id and path to file, and use Response::download($pathToFile); And restricting the uploaded files folder with .htaccess no allow?

(Assuming laravels Response::download method bypasses .htaccess) But even if that work it would probably be best to find a way to do this without .htaccess thought?

Edit I guess I will just store the files in the database as blob, and load it from there. That way I can easily do authorisation validation.

Upvotes: 3

Views: 10665

Answers (3)

vDk3
vDk3

Reputation: 81

All you have to do is just store files in a private directory (eg. /app/files) and set correct headers.

    $name = 'name.zip';
    $file = '/app/files/name.zip';

    $header = array(
        'Content-Type' => 'application/octet-stream',
        'Content-Disposition' => 'attachment', 
        'Content-length' => filesize($file),
        'filename' => $name,
    );

    // auth code
    return Response::download($file, $name, $header);

Upvotes: 8

Humble Hermit
Humble Hermit

Reputation: 133

I just came across this and maybe it can help someone too. I used this to "protect" my PDF documents to only logged in users.

I put my files outside the storage/public folder (so non of it was accessable to the public). The Controller was protected by the 'auth' middleware in the constructor.

public function grab_file($hash)
    {
        $file = Publication::where('hash', $hash)->first();

        if ($file) {
            return Response::download(storage_path('app/publications/' . $file->filename), null, [
                'Cache-Control' => 'no-cache, no-store, must-revalidate',
                'Pragma' => 'no-cache',
                'Expires' => '0',
            ], null);
        } else {
            return abort(404);
        }
}

and route is;

Route::get('/user/file/{hash}', 'UserController@grab_file');

Where Publication stored the hash reference to the file. This way there was no way for the user to "see" where the actual file was.

The "no caching" headers made sure the browser didn't cache the PDF. I did that because after logging out, you can still access the file.

Upvotes: 1

Mohamed Bouallegue
Mohamed Bouallegue

Reputation: 1362

You can restrict the access to download pages using a pattern based filter

Route::filter('download', function()
{
    //here you check if the user is logged in
    if(!Auth::check()){
        return 'you should be logged in to access the download page';
    }
});

Route::when('download/*', 'download'); 

check the documentation for more details

Upvotes: 0

Related Questions