How to allow only authenticated users access to files in Laravel

Step 1: Make the controller

In this case, we make a PDFController. Run the code below in your terminal to make your controller.

php artisan make:controller PDFController

We add the securePdf(), which will contain our logic for both the rendering and downloading of the pdf file.

You can find the newly created controller PDFController.php in the /app/Http/Controllers/ directory.

    public function securePdf($id)
    {
        $pdffile= storage_path('app/pdfs/') . $id . '.pdf';

        if (file_exists($pdffile)) { // Checking if file exist

            $headers = [
                'Content-Type' => 'application/pdf'
            ];

            return response()->download($pdffile, 'Test File', $headers, 'inline');
        } else {
            abort(404, 'File not found!');//terminate 
        }
    }

In the code above, since I use the id as an argument to the route, I will send the $id to the path of the file.

But, in your case, you can fetch the file path directly from your database or whichever way you want it.

Step 2: Protect the controller

We are going to use the auth middleware to protect the controller so that only authenticated users will have access.

<?php

namespace App\Http\Controllers;

class PDFController extends Controller
{

    public function __construct()
    {
        $this->middleware('auth');// Auth middleware used to protect the middleware.
    }

    public function securePdf($id)
    {
        $pdffile = storage_path('app/pdfs/') . $id . '.pdf';//using `$id` to fetch our file as explained

        if (file_exists($pdffile)) {
            //Ensuring that the file exist
            $headers = [
                'Content-Type' => 'application/pdf'
            ];

            return response()->download($pdffile, 'Test File', $headers, 'inline');// Send the pdf file for the user to download
        } else {
            abort(404, 'File not found!');
        }
    }
}

Step 3: Set up the route

Go to /routes/web.php directory and add the following line of code to it.

Route::get('/preview-pdf/{id}', 'PDFController@securePdf'); // the `{id}` will contain the pdf id used to fetch the file from the directory.

How to test the code

Visit /preview-pdf/{id}. Instead of the {id}, you will manually enter an id(number) of the name if you visit as an authenticated user. You will then see that your file is ready for download.

Free Resources