Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Loach's avatar
Level 11

Spatie Media Library some public some private

Hi,

I use the code below to set my files to public. The only problem is I want some of the to be private as well. What is a clever way to do this? The files are being hosted on digital ocean spaces and I need some public like for a photo gallery, other like video I would like to be private and use a signed url.


    'remote' => [
        /*
         * Any extra headers that should be included when uploading media to
         * a remote disk. Even though supported headers may vary between
         * different drivers, a sensible default has been provided.
         *
         * Supported by S3: CacheControl, Expires, StorageClass,
         * ServerSideEncryption, Metadata, ACL, ContentEncoding
         */
        'extra_headers' => [
            'CacheControl' => 'max-age=604800',
            'visibility' => 'public',
        ],
    ],
0 likes
8 replies
jlrdw's avatar

Serve through a route where authentication and authorization is required:

https://laravel.io/forum/04-23-2015-securing-filesimages

I use part of user id in file name:

class ImageController {

    public function displayImage() {

        $basedir = storage_path('app/upload');
        $imagedir = Request::input('dir');
        $image = Request::input('img');
        $string = $image;
        $str = (int) Cln::findId($string, "_", ".");

        If (Auth::id() != $str) {
          exit(0);
        }
        
        if (Auth::check()) {
            $file = $basedir . '/' . $imagedir . '/' . $image;
            return response()->file($file, array('Content-Type' => 'image/jpeg'));
        }

    }

But you can code something similar, above the logged in users id has to match.


image name ann_1457z1-55551234_127.jpg  (just example)

Logged in user id = 127

Match, will display.

But if user 147 is logged in, they cannot view the above image.
Loach's avatar
Level 11

@jlrdw thanks but I am not sure you understand the issue. I am serving the files from digital ocean spaces, some need to be public for instance a photo gallery.... the images need to be public, but other like for a video player... the videos need to be private ... meaning not accessible by anyone and I would use a signed url for the videos. I will update my post to be more specific.

jlrdw's avatar

That's similar, you still use an authorized key to view the videos. D.O spaces has nothing to do with securing files. I don't even put secure files anywhere on a web folder, I place them in another folder somewhere in the drive.

For videos why aren't you using Vimeo.

Edit: Digital Ocean also has tutorials in using their storage. But a signed url is similar to having a number in the file name that has to match.

Have you seen https://github.com/spatie/url-signer

Loach's avatar
Level 11

Digital Ocean does have something to do with securing files. I you set them to public anyone can view them with a direct link. If you set them to private they are not accessible via a direct link. Vimeo is expensive.....

Loach's avatar
Level 11

OK thanks. Back to the original question how to be able to set some private and some public with spatie media library? If I use the Storage facade I can easily do this via the “put” method and passing “public” as an argument.... but see no easy way to do it via spatie media library. I know I can just put them all private and use a signed url... but it would be expensive operation if a photo gallery had hundreds of photos. I need the option to set both “public” and “private”

jlrdw's avatar

The idea would be to store public files (media library images) as just that, store using laravel storage. Just have the private files stored securely.

Or as said make a folder somewhere on drive, (out of any web folder) and serve via a script. Many ways to achieve this. Was pretty standard in Java to have an "outside" folder to serve files from, but I only did images, never video.

Please or to participate in this conversation.