How do I use signedUrls with Linode Object Storage
I am using Node to generate a pre-signed URL using aws-sdk
. The signedUrl is generated, but when the front-end uses it to upload, it gets a 403 error.
Node:
const s3 = new S3({
endpoint: S3_ENDPOINT,
accessKeyId: AWS_ACCESS_KEY_ID,
secretAccessKey: AWS_SECRET_ACCESS_KEY,
sslEnabled: true,
// region: AWS_REGION,
signatureVersion: 'v4',
s3DisableBodySigning: true,
s3ForcePathStyle: true,
signatureCache: false,
params: {
Headers: {
Authorization: `Bearer ${LINODE_ACCESS_TOKEN}`
}
}
})
const presignedUrl = await s3.getSignedUrlPromise('putObject', {
Bucket: BUCKET_NAME,
Key: filename,
Expires: 180,
ACL: 'public-read',
ContentType: contentType,
})
Front-end:
const { presignedUrl, filename } = await client.get(`/user/${user.name}/avatar-signed-url`, {
query: {
'content-type': resizedImage.type,
},
});
const putAvatarRequest = superagent.put(presignedUrl);
putAvatarRequest.send(resizedImage);
this.progressHandler(50);
putAvatarRequest.end((err, response) => {
if (err) {
console.error(err);
return Promise.reject(err);
}
this.progressHandler(100);
this.submitHandler({
avatar: filename,
});
});
return;
});
The response I get is:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<RequestId>tx00000000000000050ca2f-005f7bec57-e44dff-default</RequestId>
<HostId>e44dff-default-default</HostId>
</Error>
1 Reply
I may have resolved this either by:
This on the front-end (see rest above):
const putAvatarRequest = superagent.put(presignedUrl);
putAvatarRequest.set({
'content-type': resizedImage.type,
'x-amz-acl': 'public-read',
'Key': filename
})
putAvatarRequest.send(resizedImage);
Difference there is I added those 3 headers with .set
Or on the back-end by removing the params that I placed there while experimenting.