Hello,
Im currently developing a React webapp that lets users upload images. I have it working with AWS S3 but would like to have everything on DO for simplicities sake.
The flow goes like this:
When i try this with spaces im constantly getting a “SignatureDoesNotMatch” error.
Please help, im going batty!
Here’s my node server code:
spacesEndpoint = new aws.Endpoint(`${DO_REGION}.digitaloceanspaces.com`),
s3 = new aws.S3({
endpoint: spacesEndpoint,
accessKeyId: DO_ACCESS_KEY_ID,
secretAccessKey: DO_SECRET_ACCESS_KEY,
region: DO_REGION,
signatureVersion: 'v4',
});
const s3Params = {
Bucket: DO_SPACE,
Expires: 60,
Key: filePath,
ContentType: fileType, // "image/jpeg"
ACL: 'public-read',
};
const promise = new Promise((resolve, reject) => {
s3.getSignedUrl('putObject', s3Params, (err, url) => {
if (err) {
reject(err);
}
resolve(url);
});
});
and this is my javascript
const xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.open('PUT', payload.signedUrl);
xhr.setRequestHeader('Host', `${DO_SPACE}.${DO_REGION}.digitaloceanspaces.com');
xhr.setRequestHeader('x-amz-acl', 'public-read');
xhr.setRequestHeader('Content-Type', payload.file.type);
xhr.setRequestHeader('Content-Length', payload.file.size);
xhr.send(payload.file);
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hi from Spaces Engineering team!
When using presigned URLs to upload, getting SignatureDoesNotMatch usually means that the headers that were used in signing don’t match the actual headers sent by the real request.
It would help tremendously if you could post one of the signed URLs, as well as the entire HTTP headers for both the request & response sent by the client using the presigned URL.
To avoid security issues, you should redact the following from them before posting:
OPTIONS request and no PUT request?Looks like your client is enforcing CORS, so you’ll need to do that first: https://www.digitalocean.com/docs/spaces/how-to/cors/
Since your Origin is Origin: http://0.0.0.0:3001, I recommend setting a CORS wildcard to start, then changing it to match your production deployment later.
P.S. The bucket name appears in multiple places, I see it leaked in your response.
OPTIONS is the HTTP method used for the CORS preflight request, to ask which other methods are permitted, based on the Access-Control-*, Origin headers that are sent, which are checked against the stores CORSConfiguration for a matching CORSRule.
A good group of settings for a single CORSRule during development:
Allowed Origin: *AllowedMethod: (all of them)AllowedHeader: * (important in dev, extra headers in SDKs can cause CORS preflight to fail)MaxAgeSeconds: 600AllowedHeader: * will help you the most I think, as I see Postman-Token in your request, you didn’t include that in the allowed headers you showed.
You said you got a SignatureDoesNotMatch in the original post, could you please reproduce that error and share the request/response headers&body for that instance?
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.