Temporary preview URLs for file uploads on S3

I’m having trouble getting temporary preview URLs to work for file uploads when using S3. Locally they work fine and regular uploads to S3 via the server are working fine too but there seems to be something about the signed URL being generated in the first request that S3 doesn’t like when it’s send in the second request.

I’m following the instructions at https://laravel-livewire.com/docs/2.x/file-uploads#preview-urls and I have added 'disk' => 's3' to my livewire.config.

This is all I get in dev tools:

And if I try to visit the signed URL myself in the browser, I get the following:

<Error>
    <Code>SignatureDoesNotMatch</Code>
    <Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message>
    <AWSAccessKeyId>AKIAUUKJDRT3M55CTZ5F</AWSAccessKeyId>
    <StringToSign>AWS4-HMAC-SHA256 20201007T153137Z 20201007/eu-west-1/s3/aws4_request 2e169f1e14479b20f7393a0f093bd8b551029b24636328871b54e5905b21d24c</StringToSign>
    <SignatureProvided>abbac803f5dcbd09dfaacf2cb9c676dc4af90bc04014089cf094804cbd338629</SignatureProvided>
    <StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 30 31 30 30 37 54 31 35 33 31 33 37 5a 0a 32 30 32 30 31 30 30 37 2f 65 75 2d 77 65 73 74 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 32 65 31 36 39 66 31 65 31 34 34 37 39 62 32 30 66 37 33 39 33 61 30 66 30 39 33 62 64 38 62 35 35 31 30 32 39 62 32 34 36 33 36 33 32 38 38 37 31 62 35 34 65 35 39 30 35 62 32 31 64 32 34 63</StringToSignBytes>
    <CanonicalRequest>GET /livewire-tmp/QVaaT9bMLBpbo7CWp0jjRUejt5DEnN-metabG9nby1kYXJrLnN2Zw%3D%3D-.svg X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAUUKJDRT3M55CTZ5F%2F20201007%2Feu-west-1%2Fs3%2Faws4_request&X-Amz-Date=20201007T153137Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=private host:ontefl-test.s3.eu-west-1.amazonaws.com x-amz-acl:private host;x-amz-acl UNSIGNED-PAYLOAD</CanonicalRequest>
    <CanonicalRequestBytes>47 45 54 0a 2f 6c 69 76 65 77 69 72 65 2d 74 6d 70 2f 51 56 61 61 54 39 62 4d 4c 42 70 62 6f 37 43 57 70 30 6a 6a 52 55 65 6a 74 35 44 45 6e 4e 2d 6d 65 74 61 62 47 39 6e 62 79 31 6b 59 58 4a 72 4c 6e 4e 32 5a 77 25 33 44 25 33 44 2d 2e 73 76 67 0a 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 6f 6e 74 65 6e 74 2d 53 68 61 32 35 36 3d 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 55 55 4b 4a 44 58 50 33 4d 35 35 43 54 5a 35 46 25 32 46 32 30 32 30 31 30 30 37 25 32 46 65 75 2d 77 65 73 74 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 32 30 31 30 30 37 54 31 35 33 31 33 37 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 33 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 68 6f 73 74 25 33 42 78 2d 61 6d 7a 2d 61 63 6c 26 78 2d 61 6d 7a 2d 61 63 6c 3d 70 72 69 76 61 74 65 0a 68 6f 73 74 3a 6f 6e 74 65 66 6c 2d 74 65 73 74 2e 73 33 2e 65 75 2d 77 65 73 74 2d 31 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 78 2d 61 6d 7a 2d 61 63 6c 3a 70 72 69 76 61 74 65 0a 0a 68 6f 73 74 3b 78 2d 61 6d 7a 2d 61 63 6c 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
    <RequestId>71F255A9E75B42C2</RequestId>
    <HostId>A63ThJYwR94yYdOolj9avclmMDtvgO7pqiYIKJpRtqbsUkg6xZOH4xHtmeRi1vX3C1AewuxWv8o=</HostId>
</Error>

Take a look on this video on S3 Part it may help you

Thank you @skywalker the video looks like a great explanation but he seems to be using local storage for temporary the preview URLs and iss only hitting S3 for the main file upload. I already have that part working properly.

Update: I now understand that the SignatureDoesNotMatch I pasted above is correct in that it’s supposed to say that because the file isn’t present when accessing the URL with a GET request.

So, I just tried using Postman to send the PUT request (with the file) to S3 using the presigned URL generated by Livewire and it works fine, the file appears inside livewire-tmp in my S3 bucket.

So I’m convinced that Livewire generated the correct presigned URL and I’m convinced that my S3 bucket is set up properly. What I’m unsure about is whether Livewire is sending the file to S3 properly at execution time. The most frustrating thing is that it’s failing with “Failed to load response data” so I don’t know what’s going on.

I cloned Caleb’s private Surge repo (which is obviously working for Caleb in the screencasts) and I’m still getting the same problem.

Ok, solved it. I was paying so much attention to the Network tab in dev tools that I forgot to look at the console and see the CORS error :grimacing:

So, anyway, yeah, I put this in my bucket CORS config and all is working well now:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>PUT</AllowedMethod>
    <AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>

That’s Great @joseph-d I’m Glade you find the solution

1 Like