alexvolley's avatar

Display images stored in S3 in blade files

Hi,

I am trying to store images in S3 and then display them on blade files in my application however I am getting a 403 Forbidden error when trying to load the image.

My IAM user has full access to S3 and I have uploaded the image through the application but seem to be unable to display it.

<img class="border-gray" height="50px;" src="{{ Storage::disk('s3')->url($this->company->logo) }}" alt="...">

I have had no issues with uploading/downloading files but for some reason I am unable to display the image, any advice would be appreciated.

Thankyou!

0 likes
13 replies
alexvolley's avatar

I already have that installed or I wouldn't have been able to do the uploads

warpig's avatar

Hi @chaudigv in regards of versions could you help me figuring out what's the best decision to make? I am also trying to use S3 but I haven't yet installed due to this message:

- league/flysystem-aws-s3-v3[2.0.0, ..., 2.x-dev] require league/flysystem ^2.0.0 -> found league/flysystem[2.0.0-alpha.1, ..., 2.x-dev] but the package is fixed to 1.1.3 (lock file version) by a partial update and that version does not match. Make sure you list it as an argument for the update command.

What would be the best decision to make here, should I go to composer.lock file and change the number, or if I wanted to update that version, what command should I be using? It says my version of league/flysystem is fixed to 1.1.3 so what does it mean by "partial update"? I understand it that I could either change the number or that I could update to a newer version inside composer.lock, but how? Would I state the composer update league/flysystem in the composer.lock file? Many thanks and I will understand if you're not able to reply since I didn't started this conversation! :-)

chaudigv's avatar

@alexvolley Apply a new policy (bucket -> permissions -> Bucket policy) to the user below, replacing "my-bucket" with your bucket slug.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket",
                "s3:ListAllMyBuckets",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl", 
                "s3:GetObject",
                "s3:DeleteObject"
            ],
            "Resource": [
                "arn:aws:s3:::my-bucket/*"
            ]
        }
    ]
}
chaudigv's avatar

@warpig Currently Laravel supports version 1.

I suggest update your composer.json file with "league/flysystem-aws-s3-v3": "^1.0", and then run composer update league/flysystem-aws-s3-v3. The update command with update your composer.lock file.

should i go to composer.lock file and change the number

NEVER DO THAT Let the composer insert/update command deal with the versioning of the packages.

1 like
warpig's avatar

Thanks! That's why I like this forum so I can prevent catastrophes! Since I don't have it inside the composer.json under which object should I place it? Something like this:

"require": {
"league/flysystem-aws-s3-v3": "^1.0",
},

Like this? and then running the composer update...

alexvolley's avatar

I seem to be getting the same result with this as i was before.

as a note because i was using the AmazonS3FullAccess Policy the json was previously which should allow everything anyway should it not:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": "*"
        }
    ]
}
martinbean's avatar
Level 80

@alexvolley IAM permissions isn’t really going to do much when it’s a HTTP request being made to the image.

If the file is stored using the private ACL, then you will need to use a signed URL to view the image. You can do this using Laravel’s filesystem adapter:

<img src="{{ Storage::disk('s3')->temporaryUrl($this->company->logo, '+2 minutes') }}">
4 likes
warpig's avatar

Why is this not working for me? I just ran into the 403 error, my store() method:

        if ($post->image_url = $request->has('image')) {
            $path = Storage::disk('s3')->put('images/', $request->file('image'), 'public');
            $post->image_url = basename($path);
        }

Then I removed the publicbecause the permissions are set to private but the image isn't being displayed

        if ($post->image_url = $request->has('image')) {
            $path = Storage::disk('s3')->put('images/', $request->file('image'));
            $post->image_url = basename($path);
        }

From the docs I should display it by using something like: $contents = Storage::get('file.jpg'); so in my case I should pass this variable in the show() ? and on the view something like this?:

        <img src="{{ Storage::disk('s3')->temporaryUrl($post->image_url->contents, '+2 minutes') }}">
YasirAmeen's avatar

@warpig Try this:

// For Store
if ($request->hasFile('image')) {
    $file = $request->file('image');
    $filePath = 'images';
    $post->image = Storage::disk('s3')->put($filePath, $file);
}
//For Display
<img src="{{ Storage::disk('s3')->temporaryUrl($post->image, '+2 minutes') }}">
Stainz_420's avatar

@martinbean Many thanks, good sir. You deserve a Nobel prize for this. Finally a solution that actually works! I made an account on here right now just so I could write this comment to express my gratitude.

1 like

Please or to participate in this conversation.