6

I'm using Javascript SDK on AWS Lambda to generate signed URL. But getSignedUrl is only returning path style URL. I have tried setting s3ForcePathStyle as false.

const params = {
    Bucket: 'bucket_name',
    Key: 'key_name'
};

const options = {
    signatureVersion: 'v4',
    useAccelerateEndpoint: false,
    // endpoint: new AWS.Endpoint('https://bucket_name.s3.amazonaws.com'),
    s3ForcePathStyle: false 
};

const client = new AWS.S3(options);
exports.handler = async (event) => {

    const signedURL = await (new Promise((resolve, reject) => {
        client.getSignedUrl('putObject', params, (err, data) => {
            if (err) {
                reject(err);
            } 
            else {
                resolve(data);
            }
         });
    }));
    return signedURL;
};

If I uncomment endpoint: new AWS.Endpoint('https://bucket_name.s3.amazonaws.com') I'm getting an absurd URL which combines both:

https://bucket_name.s3.amazonaws.com/bucket_name/key_name......

tl;dr

https://s3.ap-south-1.amazonaws.com/bucket_name/key_name..... # Code returns path-style
https://bucket_name.s3.amazonaws.com/key_name..... # I want virtual-hosted-style
secretshardul
  • 1,635
  • 19
  • 31
  • Can you explain why you want this style? What benefit does it give you? – Joey Kilpatrick Nov 24 '19 at 18:54
  • I plan to run an API-as-a-service. I don't want customers to see the bucket URL. For this I'll be using [CNAMEs](https://docs.aws.amazon.com/AmazonS3/latest/dev/VirtualHosting.html#VirtualHostingCustomURLs) for my own domain. According to documentation ```Setting the alias target to s3.amazonaws.com also works, but it may result in extra HTTP redirects``` – secretshardul Nov 25 '19 at 03:43
  • Came across this question for reasons of Content-Security-Policy – Danylo Fedorov Jun 23 '22 at 14:48

1 Answers1

0

If you have the key of the object there is another approach by giving the presigner an unsigned url in the virtual-hosted-style format.

const unsignedUrl = parseUrl("https://bucket_name.s3.region.amazonaws.com/key_name")
const presigner = new S3RequestPresigner({
    credentials,
    region,
    sha256: Hash.bind(null, "sha256")
});
const signedURL = await presigner.presign(new HttpRequest(unsignedUrl))
return formatUrl(signedURL)

See this blog post from 2021 (with object url) and the current doc