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

AWS STS凭证上传过期问题:如何中途更新凭证或自动重试?

解决AWS SDK v2大文件上传STS凭证过期问题

方案一:自定义自动刷新的STS凭证提供者

AWS SDK v2支持自定义Credentials类,通过实现refresh方法,让SDK在凭证过期时自动获取新凭证,无需手动干预。

代码实现

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

class CustomSTSCredentials extends AWS.Credentials {
  constructor(initialCreds) {
    // 初始化初始凭证
    super(initialCreds.aws_access_key_id, initialCreds.aws_secret_access_key, initialCreds.aws_session_token);
    // 将过期时间转为Date对象
    this.expires = new Date(initialCreds.expires_at);
  }

  // 自定义凭证刷新逻辑
  async refresh(callback) {
    try {
      // 调用你的服务器接口获取新的STS凭证
      const newCreds = await fetch('/your-server-sts-api', {
        method: 'POST',
        body: JSON.stringify({
          bucket_name: '你的存储桶名',
          basepath: '文件上传路径前缀'
        })
      }).then(res => res.json());

      // 更新凭证信息
      this.accessKeyId = newCreds.aws_access_key_id;
      this.secretAccessKey = newCreds.aws_secret_access_key;
      this.sessionToken = newCreds.aws_session_token;
      this.expires = new Date(newCreds.expires_at);

      callback(null);
    } catch (err) {
      callback(err);
    }
  }
}

// 初始化S3客户端,使用自定义凭证
const s3 = new AWS.S3({
  region: bucket_region,
  credentials: new CustomSTSCredentials(initialStsCredentials),
  correctClockSkew: true
});

// 正常执行上传
s3.upload({
  Bucket: bucket_name,
  Key: `${basepath}/目标文件名`,
  Body: 大文件流,
  ACL: acl
}, (err, data) => {
  if (err) {
    console.error('上传失败:', err);
  } else {
    console.log('上传成功:', data.Location);
  }
});

原理说明

SDK会自动监控凭证的过期时间,当凭证即将过期或已过期时,自动调用refresh方法获取新凭证,然后继续分块上传的后续请求,全程无需手动介入。


方案二:捕获过期错误后手动更新凭证并重试

如果自定义凭证提供者不符合你的场景,可以捕获ExpiredToken错误,手动获取新凭证后重试上传。

代码实现

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

let currentStsCreds = initialStsCredentials;
const s3 = new AWS.S3({
  region: bucket_region,
  correctClockSkew: true
});

// 封装带重试逻辑的上传函数
async function uploadWithRetry(uploadParams, retryCount = 0) {
  try {
    // 每次重试前更新S3客户端的凭证
    s3.config.update({
      accessKeyId: currentStsCreds.aws_access_key_id,
      secretAccessKey: currentStsCreds.aws_secret_access_key,
      sessionToken: currentStsCreds.aws_session_token
    });

    const result = await s3.upload(uploadParams).promise();
    return result;
  } catch (err) {
    // 判断是否为凭证过期错误,且重试次数未超限
    if (err.code === 'ExpiredToken' && retryCount < 3) {
      // 获取新的STS凭证
      currentStsCreds = await fetch('/your-server-sts-api', {
        method: 'POST',
        body: JSON.stringify({
          bucket_name: uploadParams.Bucket,
          basepath: uploadParams.Key.split('/').slice(0, -1).join('/')
        })
      }).then(res => res.json());

      // 重试上传
      return uploadWithRetry(uploadParams, retryCount + 1);
    }
    // 非过期错误或重试超限,抛出原错误
    throw err;
  }
}

// 调用上传函数
uploadWithRetry({
  Bucket: bucket_name,
  Key: `${basepath}/目标文件名`,
  Body: 大文件流,
  ACL: acl
})
.then(data => console.log('上传成功:', data.Location))
.catch(err => console.error('上传失败:', err));

注意事项

  • 需限制重试次数,避免因服务器无法返回有效凭证导致无限循环。
  • 确保新获取的STS凭证权限与原凭证一致,且针对同一存储桶和路径。

内容的提问来源于stack exchange,提问作者transient eternity

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 05:43:11