You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Node.js中创建有效期36小时的AWS S3文件下载预签名URL?Lambda代码过期异常及STS使用疑问

Hey there! Let's break down how to fix your presigned URL expiration issues and get that 36-hour working link set up properly.

First, let's fix the immediate problem in your original code

Your initial getSignedUrl method ignores the incoming parameters entirely—you're hardcoding Bucket, Key, and Expires values instead of using the ones passed into the function. That's why your Expires parameter wasn't taking effect. On top of that, Lambda's default execution role credentials only last 1 hour, so even if you fixed the parameter issue, the presigned URL couldn't outlive those credentials.

The fix: Use STS AssumeRole for long-lived credentials

To generate a presigned URL that lasts up to 36 hours, you need to:

  1. Use STS assumeRole to get temporary credentials with a longer expiration (max 36 hours, which matches your requirement)
  2. Create an S3 client using those temporary credentials
  3. Generate the presigned URL using this client, with an expiration that doesn't exceed the STS credentials' lifespan

Here's the updated, working version of your AwsS3Repository class, using async/await to avoid callback hell and align with your original code style:

'use strict';
const AWS = require('aws-sdk');

class AwsS3Repository {
    constructor() {
        // Set your AWS region (you can also use environment variables for this)
        AWS.config.update({ region: 'your-region' });
        this.sts = new AWS.STS({ apiVersion: '2011-06-15' });
    }

    async getSignedUrl({ bucketName, Key, Expires = 36 * 3600 }) {
        try {
            // 1. Assume the STS role to get long-lived temporary credentials
            const roleAssumptionParams = {
                RoleArn: 'arn:aws:iam::your-account-id:role/your-sts-role', // Replace with your STS role ARN
                RoleSessionName: `s3-presign-session-${Date.now()}`,
                DurationSeconds: Expires, // Match the expiration to your desired URL lifespan
            };

            const stsResponse = await this.sts.assumeRole(roleAssumptionParams).promise();
            const tempCredentials = {
                accessKeyId: stsResponse.Credentials.AccessKeyId,
                secretAccessKey: stsResponse.Credentials.SecretAccessKey,
                sessionToken: stsResponse.Credentials.SessionToken,
            };

            // 2. Create an S3 client using the temporary credentials
            const s3 = new AWS.S3({ credentials: tempCredentials });

            // 3. Generate the presigned URL with the correct parameters
            const presignParams = {
                Bucket: bucketName,
                Key: Key,
                Expires: Expires,
            };

            return s3.getSignedUrl('getObject', presignParams);
        } catch (error) {
            console.error('Failed to generate long-lived presigned URL:', error);
            throw error;
        }
    }
}

module.exports = AwsS3Repository;

Critical things to double-check

  • STS Role Trust Policy: Make sure your STS role's trust policy allows your Lambda execution role to assume it. Example trust policy:
    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": "arn:aws:iam::your-account-id:role/your-lambda-execution-role"
          },
          "Action": "sts:AssumeRole"
        }
      ]
    }
    
  • STS Role Permissions: The STS role needs permission to perform s3:GetObject on the target S3 bucket and objects.
  • Lambda Execution Role Permissions: Your Lambda's execution role must have permission to call sts:AssumeRole on your STS role.
  • Expiration Limits: The maximum DurationSeconds for STS credentials is 36 hours (129600 seconds)—don't set Expires higher than this.

内容的提问来源于stack exchange,提问作者Gabriel Costa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 13:08:11