简体   繁体   中英

AWS S3 JavaScript SDK getSignedUrl returns base path only

I have some very simple code for generating an S3 URL. The URL I get back from the SDK only has the base path for S3. It doesn't contain anything else. Why is this happening?

var AWS = require('aws-sdk');

var s3 = new AWS.S3();

console.log(s3.getSignedUrl('getObject', {
  Bucket: 'test',
  Key: 'test'
}));

// Returns "https://s3.amazonaws.com/"

Node.js v0.12.0, AWS SDK 2.1.15 or 2.1.17, Windows 7 64-bit,

The problem wasn't with code. It turns out that when you don't have your AWS credentials set up properly in your environment that the AWS SDK doesn't complain. Fixing the credentials in ~/.aws/credentials resolved the issue.

I too had the same problem. I got the correct output by changing the below

from AWS_Access_Key_Id = myaccesskey to aws_access_key_id=myaccesskey

Similarly for Secret key. That means you should not use Upper case and no space before and after =

To trace your issue whether your bucket exists with right permissions, and/or credentials are correct in your ~/.aws/credentials file, or whatever other aws access related problems. I just used the (Headbucket) operation as per documentation.

Ref: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrlPromise-property

to achieve this programmatically:

 /* This operation checks to see if a bucket exists. Put into aws.ts files*/ var params = { Bucket: "acl1" }; s3.headBucket(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response });

Meanwhile the callback:

 var params = { Bucket: 'STRING_VALUE', /* required */ ExpectedBucketOwner: 'STRING_VALUE' /* the owner's aws account id */ }; s3.headBucket(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response });

This will throw an exception like:

for example => CredentialsError: Missing credentials in config, if using AWS_CONFIG_FILE...

I had the same problem.

I inserted a correct access token, but some requests received only basepath, and some requests received normal URLs.

I was able to get the correct URL when I modified getSignedUrl to await getSignedUrlPromise .

EC2 IAM Roles

If you're getting this issue when you are using EC2 IAM roles (such as in Fargate) and your code is something like this:

const url = await s3.getSignedUrl('getObject', params);

You should call this method with its asynchronous callback. Easiest is probably with a Promise wrap.

const url = await new Promise((resolve, reject) =>
    s3.getSignedUrl('getObject', params, (err, url) => {
        if (err) {
          reject(err);
        } else {
          resolve(url);
        }
    }),
);

FromS3 Documentation

Note: You must ensure that you have static or previously resolved credentials if you call this method synchronously (with no callback), otherwise it may not properly sign the request. If you cannot guarantee this (you are using an asynchronous credential provider, ie, EC2 IAM roles), you should always call this method with an asynchronous callback.

Next, is make sure to give correct permissions to the Role.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Resource": "Bucket/*"
        }
    ]
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM