skip to Main Content

I don’t know what happened in the last 24 hours that caused this thing to break, but it had been working perfectly for 3 years, non stop without issues. Trust me, I haven’t changed any code. As a matter of fact, I haven’t pushed code for 2 weeks.

Basically, I am using Laravel 6 and Laravel Vapor to upload files to S3 using the Signed URLs mechanism that the framework provides. Ever since this morning, I am seeing the following issue. The AWS PHP SDK is 3.148.3, by the way.

<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>[REDACTED]</AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256 20220712T203731Z 20220712/eu-west-2/s3/aws4_request 961d5d32676be187af1a7ccf8a92b8c29e2d851bdd51c46836aedce7cc9e089a</StringToSign>
<SignatureProvided>101e80ad27bfe4ed12a34b19fff4c17f87a3f639b92d62c8e7a79b13c876b1ca</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 32 32 30 37 31 32 54 32 30 33 37 33 31 5a 0a 32 30 32 32 30 37 31 32 2f 65 75 2d 77 65 73 74 2d 32 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 39 36 31 64 35 64 33 32 36 37 36 62 65 31 38 37 61 66 31 61 37 63 63 66 38 61 39 32 62 38 63 32 39 65 32 64 38 35 31 62 64 64 35 31 63 34 36 38 33 36 61 65 64 63 65 37 63 63 39 65 30 38 39 61</StringToSignBytes>
<CanonicalRequest>GET /tmp/0344aa31-c756-49c3-8ce1-932ec23c895d X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=[REDACTED]%2F20220712%2Feu-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220712T203731Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host%3Bx-amz-acl&x-amz-acl=public-read host:[REDACTED].s3.eu-west-2.amazonaws.com x-amz-acl:public-read host;x-amz-acl UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>47 45 54 0a 2f 74 6d 70 2f 30 33 34 34 61 61 33 31 2d 63 37 35 36 2d 34 39 63 33 2d 38 63 65 31 2d 39 33 32 65 63 32 33 63 38 39 35 64 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 34 58 4b 4a 50 55 57 34 55 43 42 4a 49 32 57 57 25 32 46 32 30 32 32 30 37 31 32 25 32 46 65 75 2d 77 65 73 74 2d 32 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 32 30 37 31 32 54 32 30 33 37 33 31 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 75 62 6c 69 63 2d 72 65 61 64 0a 68 6f 73 74 3a 73 68 61 64 6f 77 66 6f 75 6e 64 72 2d 75 70 6c 6f 61 64 73 2d 6c 6f 63 61 6c 2e 73 33 2e 65 75 2d 77 65 73 74 2d 32 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 75 62 6c 69 63 2d 72 65 61 64 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>S6E8RFNVQ3WGAAHB</RequestId>
<HostId>yA998rWcqzfVIdD9HyrIJRJtbI/ge5opCEHEgpPoBBAuwRjgABub590OnA66JVHwyxHdo/a2uB6+ii/IxwZIGw==</HostId>
</Error>

Vue.js

@change=upload

convertFileNameToKebabCase(fileNameRaw) {
    let fileNameActual = _.kebabCase(fileNameRaw.split(".").shift());
    let fileExtension = fileNameRaw.split(".").pop();

    return `${fileNameActual}.${fileExtension}`;
  },
  async store(file, options = {}, fileAcl) {
      const response = await Vue.axios.post(
        "/vapor/signed-storage-url", {
          bucket: options.bucket || "",
          content_type: options.contentType || file.type,
          expires: options.expires || "",
          visibility: fileAcl || "",
          ignore_web_middleware: true
        }, {
          baseURL: options.baseURL || null,
          headers: options.headers || {}
        }
      );

      let headers = response.data.headers;

      if ("Host" in headers) {
        delete headers.Host;
      }

      if (typeof options.progress === "undefined") {
        options.progress = () => {};
      }

      // Reset axios instance as Amazon
      // does not like our Auth header

      const newInstance = axios.create();
      await newInstance.put(response.data.url, file, {
        headers: headers,
        onUploadProgress: progressEvent => {
          options.progress(
            progressEvent.loaded / progressEvent.total
          );
        }
      });

      response.data.extension = file.name.split(".").pop();

      return response.data;
    },
    async upload(event) {
      const {
        valid
      } = await this.$refs.provider.validate(event);

      if (valid) {
        this.reset();
        let fileData = this.$refs.file.files[0];

        this.fileName = fileData.name;
        this.url = false;

        try {
          const response = await this.store(
            this.$refs.file.files[0], {
              progress: progress => {
                this.uploadProgress = Math.round(progress * 100);
              }
            },
            "public-read"
          );

          Vue.axios
            .post("/file/commit", {
              uuid: response.uuid,
              key: response.key,
              bucket: response.bucket,
              name: this.convertFileNameToKebabCase(this.$refs.file.files[0].name),
              content_type: this.$refs.file.files[0].type
            })
            .then(success => {
              this.reset();
              this.url = success.data.data.file;
              this.uploadCompleted = true;
            })
            .catch(error => {
              this.reset();
              this.uploadFailed = true;
            });
        } catch (error) {
          this.reset();
          this.uploadFailed = true;
        }
      }
    },

2

Answers


  1. Chosen as BEST ANSWER

    I found the solution. I had to remove the following in the headers: x-amz-acl. I do not know why this was the problem but it seems to have worked. Hope if anyone comes across this in the future, try this solution.

    if ("Host" in headers) {
       delete headers.Host;
       delete headers["x-amz-acl"];
    }
    

  2. Three things to check:

    1. Region mismatch, the bucket is in region X but CLI/SDK goes to Region Y.
    2. A corruption or unusual setting in your AWS CLI profile, reset the
      profile, check if access key and secret are still valid.
    3. CORS configuration not containing <AllowedHeader>*</AllowedHeader>

    Otherwise could you share some more details on the code that causes the error?

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search