使用Node.js AWS-SDK时遇"Could not load credentials from any providers"错误
解决S3复制文件时的CredentialsError问题
我编写了一段Node.js代码用于在S3存储桶内复制文件,逻辑是先列出源路径下的所有对象,再逐个复制到目标路径。代码如下:
const AWS = require('aws-sdk'); const s3 = new AWS.S3({ accessKeyId: process.env.ACCESS_KEY, sercetAccessKey: process.env.SECRET_ACCESS_KEY, // region: "ap-south-1", endpoint: process.env.S3_ENDPOINT, }); // console.log(process.env.S3_BUCKET) async function copyS3Folder(sourcePrefix, destinationPrefix, continuationToken) { try { // List all objects in the source folder const listParams = { // accessKeyId: process.env.ACCESS_KEY, Bucket: process.env.S3_BUCKET || "", Prefix: sourcePrefix, ContinuationToken: continuationToken }; const listedObjects = await s3.listObjectsV2(listParams).promise(); if (!listedObjects.Contents || listedObjects.Contents.length === 0) return; // Copy each object to the new location await Promise.all(listedObjects.Contents.map(async (object) => { if (!object.Key) return; let destinationKey = object.Key.replace(sourcePrefix, destinationPrefix); let copyParams = { Bucket: process.env.S3_BUCKET || "", CopySource: `${process.env.S3_BUCKET}/${object.Key}`, Key: destinationKey }; console.log(copyParams); await s3.copyObject(copyParams).promise(); console.log(`Copied ${object.Key} to ${destinationKey}`); })); // Check if the list was truncated and continue copying if necessary if (listedObjects.IsTruncated) { listParams.ContinuationToken = listedObjects.NextContinuationToken; await copyS3Folder(sourcePrefix, destinationPrefix, continuationToken); } } catch (error) { console.error('Error copying folder:', error); } }
但运行时触发了如下错误:
copying folder: Error [CredentialsError]: Missing credentials in config, if using AWS_CONFIG_FILE, set AWS_SDK_LOAD_CONFIG=1 at Timeout.connectTimeout [as _onTimeout] (D:\Coding\VStart Main\server\node_modules\aws-sdk\lib\http\node.js:70:15) at listOnTimeout (node:internal/timers:573:17) at process.processTimers (node:internal/timers:514:7) { code: 'CredentialsError', time: 2024-07-12T13:08:19.491Z, retryable: true, originalError: { message: 'Could not load credentials from any providers', code: 'CredentialsError', time: 2024-07-12T13:08:19.491Z, retryable: true, originalError: { message: 'EC2 Metadata roleName request returned error', code: 'TimeoutError', time: 2024-07-12T13:08:19.491Z, retryable: true, originalError: [Object]
我尝试在函数参数中添加访问密钥,但问题依旧。
解决方案
修复凭证参数拼写错误:代码中
sercetAccessKey是拼写错误,正确参数名是secretAccessKey,这是导致凭证无法加载的直接原因。修正后的S3实例初始化代码:const s3 = new AWS.S3({ accessKeyId: process.env.ACCESS_KEY, secretAccessKey: process.env.SECRET_ACCESS_KEY, endpoint: process.env.S3_ENDPOINT, });验证环境变量有效性:
- 在代码开头添加日志,确认环境变量是否正确读取:
console.log('ACCESS_KEY:', process.env.ACCESS_KEY); console.log('SECRET_ACCESS_KEY:', process.env.SECRET_ACCESS_KEY); console.log('S3_BUCKET:', process.env.S3_BUCKET); - 确保环境变量已正确设置(比如通过
.env文件配合dotenv包,或系统环境变量)。
- 在代码开头添加日志,确认环境变量是否正确读取:
修正递归调用参数:处理分页的递归逻辑中,传递的
continuationToken参数错误,应该传递新获取的listedObjects.NextContinuationToken,否则无法正确遍历所有对象:if (listedObjects.IsTruncated) { await copyS3Folder(sourcePrefix, destinationPrefix, listedObjects.NextContinuationToken); }检查CopySource权限:如果是跨桶复制,确保源桶的权限策略允许当前凭证执行
s3:GetObject操作,目标桶允许s3:PutObject操作。同桶复制时,CopySource格式${process.env.S3_BUCKET}/${object.Key}是正确的。
内容的提问来源于stack exchange,提问作者Divyansh Pathak
相关产品推荐
相关产品推荐

