简体   繁体   English

如何在 NodeJS 中创建预签名的 url 以从 AWS-s3 存储桶下载文件 36 小时?

[英]How can I create a pre-signed url to download a file from an AWS-s3 Bucket for 36 hours in NodeJS?

My aws-lambda code right now is:我现在的 aws-lambda 代码是:


    'use strict';
    
    const AWS = require('aws-sdk');
    
    class AwsS3Repository {
      constructor() {
        this.s3 = new AWS.S3();
      }
    
      async getSignedUrl ({ bucketName, Key, Expires }) {
        const params = { 
          Bucket: "bucket_name", 
          Key: "key_name",
          Expires: 60 * 60 * 36,
        }
    
        return this.s3.getSignedUrl('getObject', params);
      }
    } 
    
    module.exports = AwsS3Repository;

While it's working, the expiration time is ignoring the parameter "expires" and instead is expiring in what seems to be less than one hour.虽然它正在工作,但到期时间忽略了参数“expires”,而是在似乎不到一小时的时间内到期。

I've read in the AWS docs that you need to use STS to create links that will be valid to 36 hours, so I've created an STS with trusted policy to my lambda function in AWS, so I'm able to use STS.assume as you can see in this example:我在AWS 文档中读到您需要使用 STS 创建有效期为 36 小时的链接,因此我在 AWS 中为我的 lambda function 创建了一个具有可信策略的 STS,因此我可以使用 STS .assume 如您在此示例中所见:


    const AWS = require('aws-sdk');
    // Set the region 
    AWS.config.update({region: 'REGION'});
    
    var roleToAssume = {RoleArn: 'my_role',
                        RoleSessionName: 'session1',
                        DurationSeconds: 900,};
    var roleCreds;
    
    // Create the STS service object    
    var sts = new AWS.STS({apiVersion: '2011-06-15'});
    
    //Assume Role
    sts.assumeRole(roleToAssume, function(err, data) {
        if (err) console.log(err, err.stack);
        else{
            roleCreds = {accessKeyId: data.Credentials.AccessKeyId,
                         secretAccessKey: data.Credentials.SecretAccessKey,
                         sessionToken: data.Credentials.SessionToken};
            stsGetCallerIdentity(roleCreds);
        }
    });
    
    //Get Arn of current identity
    function stsGetCallerIdentity(creds) {
        var stsParams = {credentials: creds };
        // Create STS service object
        var sts = new AWS.STS(stsParams);
            
        sts.getCallerIdentity({}, function(err, data) {
            if (err) {
                console.log(err, err.stack);
            }
            else {
                console.log(data.Arn);
            }
        });    
    }

 

However, I still don't understand how I will use STS to create the pre-signed url.但是,我仍然不明白我将如何使用 STS 来创建预签名的 url。

If you read the docs for getSignedUrl , you will see that expiration is specified in seconds, not in hours:如果您阅读getSignedUrl的文档,您会看到到期时间以秒为单位,而不是以小时为单位:

Expires (Integer) — default: 900 — the number of seconds to expire the pre-signed URL operation in. Defaults to 15 minutes. Expires (Integer) — 默认值:900 — 预签名的 URL 操作到期的秒数。默认为 15 分钟。

I fixed the problem by creating an IAM role that has permission to create signed url in my S3 bucket and setting it to trust my lambda through the trust policy option in AWS, then updating the AWS-SDK config to use the IAM credentials returned by the sts.assumeRole method.我通过创建一个 IAM 角色来解决该问题,该角色有权在我的 S3 存储桶中创建签名的 url,并通过 AWS 中的信任策略选项将其设置为信任我的 lambda,然后更新 AWS-SDK 配置以使用由sts.assumeRole 方法。


    async assumeRole() {
    const roleToAssume = {
      RoleArn: 'my-sts-role-in-aws',
      RoleSessionName: 'session1',
      DurationSeconds: 900,
    };

    const sts = new AWS.STS({ apiVersion: '2011-06-15' });

    const roleCreds = await sts.assumeRole(roleToAssume).promise()

    AWS.config.update({ 
      accessKeyId: roleCreds.accessKeyId,
      secretAccessKey: roleCreds.secretAccessKey,
      sessionToken: roleCreds.sessionToken,
      region: 'us-east-1',
      signatureVersion: 'v4'
    });
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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