DEV Community

Shoichi Okaniwa
Shoichi Okaniwa

Posted on Edited on Originally published at qiita.com

Handling 403 Errors When Uploading to S3 Signed URLs with Node.js

Handling 403 Errors When Uploading to S3 Signed URLs with Node.js

I encountered challenges uploading files to Amazon S3 using signed URLs with Node.js. So, here’s a rundown to avoid the same issues in the future.

I referred to this article on generating signed URLs with Node.js:
{AWS(CloudFront+S3)+Node.js} Delivering Private Content Using Signed URLs

Successfully Generated Download Signed URLs

Generating signed URLs for downloading worked smoothly with the following code:

import AWS from 'aws-sdk';

// AWS authentication details

// Create S3 instance
const s3 = new AWS.S3();

// Generate download URL
const downloadUrl = await s3.getSignedUrl('getObject', {
  Bucket: 'your-bucket-name',
  Key: 'your-object-name',
  Expires: 60,
});
Enter fullscreen mode Exit fullscreen mode

Encountering Issues with Upload Signed URLs

Using a similar approach, I generated upload signed URLs, which were created successfully.

import AWS from 'aws-sdk';

// AWS authentication details

// Create S3 instance
const s3 = new AWS.S3();

// Generate upload URL
const uploadUrl = await s3.getSignedUrl('putObject', {
  Bucket: 'your-bucket-name',
  Key: 'your-object-name',
  Expires: 60,
});
Enter fullscreen mode Exit fullscreen mode

However, when attempting to upload a file using the generated URL, I received a 403 status code. The response body looked like this:

<?xml version="1.0" encoding="UTF-8"?>
<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>hoge</AWSAccessKeyId>
    <StringToSign>hoge</StringToSign>
    <SignatureProvided>hoge</SignatureProvided>
    <StringToSignBytes>hoge</StringToSignBytes>
    <RequestId>hoge</RequestId>
    <HostId>hoge</HostId>
</Error>
Enter fullscreen mode Exit fullscreen mode

In short, it indicated an issue with the signing method.

Utilizing Signature Version 4

After further investigation, I discovered an issue:
Node.js pre-signed URL for PUT response is 'signature does not match'

As per this issue, use signature version 4 when generating the URL.

// Create S3 instance
const s3 = new AWS.S3({
  signatureVersion: 'v4',
});

// Generate upload URL
const uploadUrl = await s3.getSignedUrl('putObject', {
  Bucket: 'your-bucket-name',
  Key: 'your-object-name',
  Expires: 60,
});
Enter fullscreen mode Exit fullscreen mode

By testing uploads with the above code, I successfully uploaded files!

Conclusion

I'm relieved to have resolved this issue. Special thanks to the following articles for their clear explanations:

Top comments (0)