• Webwide.io has moved to Webwide.chat

    The Webwide.io forums are coming to a close but we hope you'll join us over on Webwide.chat! Thank you very much to all our wonderful members, please contact Adam for a free Webwide.chat membership.

Storing user files in laravel

Storing user files in laravel

TGDesigns

Member
Local time
14:39
Joined
Nov 20, 2019
Messages
89

Hi all!

Long time no post! Hope everyone who reads this is doing ok and keeping safe!

I have a bit of a dilemma, I'm using laravel to make a simple stock management system and im struggling with the logistics of storing user files, I want them to be accessible via url but the person logged in should only be able to see their product photos. Any suggestions on how to achieve this? Currently when a new product is created im saving it in "public/product_photos/{{UserID}}/{{ProductID}}" but that means someone could just switch out the id's and get a direct url to another users photo!

Cheers,
Tom

 

adam

Mr. Webwide
Administrator
Community Team
Local time
14:39
Joined
Sep 24, 2019
Messages
1,264
Pronouns
he/him

You could rename the file to a random, unguessable string and store that in the database for serving to the user? This would be the simplest way assuming that the photos weren't particularly sensitive and didn't need real authentication.

 

TGDesigns

Member
Local time
14:39
Joined
Nov 20, 2019
Messages
89

You could rename the file to a random, unguessable string and store that in the database for serving to the user? This would be the simplest way assuming that the photos weren't particularly sensitive and didn't need real authentication.
Yeah that makes sense, they arent sensitive at all its more I just didnt want one user harvesting all of another users product photos!

 

Gummibeer

Astroneer
Moderator
Local time
15:39
Joined
Oct 5, 2019
Messages
1,187
Pronouns
he/him

Adams idea is right/the simplest.
Using random tokens or UUIDs is the most common strategy for files the world won't burn if someone unauthorized access them.

#selfMarketing


This will a simple trait that adds a UUID to your model.

If these files are payment protected or something you should use a middleware/controller in between. Because no static delivery method is really secure.
The controller will also allow you to use blob storage (S3) or similar to prevent filling your server disk.
But it will increase the workload on your app/php.

Another, more fancy, approach would be to deliver directly from blob storage and use single use access tokens to load the file directly from blob storage without going through your server.

 

TGDesigns

Member
Local time
14:39
Joined
Nov 20, 2019
Messages
89

Adams idea is right/the simplest.
Using random tokens or UUIDs is the most common strategy for files the world won't burn if someone unauthorized access them.

#selfMarketing


This will a simple trait that adds a UUID to your model.

If these files are payment protected or something you should use a middleware/controller in between. Because no static delivery method is really secure.
The controller will also allow you to use blob storage (S3) or similar to prevent filling your server disk.
But it will increase the workload on your app/php.

Another, more fancy, approach would be to deliver directly from blob storage and use single use access tokens to load the file directly from blob storage without going through your server.

Just so I understand correctly each image is assigned a random uuid and then that is used as the filename and stored in the DB? Does this sort of system work when I need multiple images associated with one product? Could I have a random string as a folder and then multiple images with human readable filenames stored within the folder? Sorry if it should be simple, first time ive worked with files!

 

Gummibeer

Astroneer
Moderator
Local time
15:39
Joined
Oct 5, 2019
Messages
1,187
Pronouns
he/him

PS: if you don't have a perfect monitoring and don't fear to get a wake-up call at 2am I HIGHLY recommend you to never store user files on the server disk.
Blob storage is much cheaper, you can use a CDN infront of it and it scales endless.
So even a user with 10.000 products and TIFF images won't kill your server over night. 😉

 

Gummibeer

Astroneer
Moderator
Local time
15:39
Joined
Oct 5, 2019
Messages
1,187
Pronouns
he/him

Just so I understand correctly each image is assigned a random uuid and then that is used as the filename and stored in the DB? Does this sort of system work when I need multiple images associated with one product? Could I have a random string as a folder and then multiple images with human readable filenames stored within the folder? Sorry if it should be simple, first time ive worked with files!
Both works. In all apps we use files we have a UUID on the main model and a morphable media/file table which also contains a UUID.
The path/URL looks like:

Code:
{model_class}/{model_uuid}/{file_uuid}.{ext}
product/1234/abcd.jpg

But the file table contains all relevant information: mimetype, size, original filename and what else you need.

 
Last edited:

Gummibeer

Astroneer
Moderator
Local time
15:39
Joined
Oct 5, 2019
Messages
1,187
Pronouns
he/him

The package itself will be over-scaled for your usecase - except you want to process the images and create defined versions:


But the migration gives you an idea how our media/file models look like:


PHP:
Schema::create('files', function (Blueprint $table) {
    $table->bigIncrements('id');
    $table->morphs('model');
    $table->uuid('uuid')->nullable();
    $table->string('collection_name');
    $table->string('file_name');
    $table->string('mime_type')->nullable();
    $table->string('disk');
    $table->unsignedBigInteger('size');
    $table->nullableTimestamps();
});

 

TGDesigns

Member
Local time
14:39
Joined
Nov 20, 2019
Messages
89

Both works. In all apps we use files we have a UUID on the main model and a morphable media/file table which also contains a UUID.
The path/URL looks like:

Code:
{model_class}/{model_uuid}/{file_uuid}.{ext}
product/1234/abcd.jpg

But the file table contains all relevant information: mimetype, size, original filename and what else you need.
Ok thanks for the information! I think im gonna go with something like this http://localhost/storage/{userID}/product_images/2dc24d7a-27db-4a25-9132-fd0ae3ad6dc9/Main_image.jpg

 
Top