Node.js中@aws-sdk/client-s3仅加载.env中AWS凭证的配置问题
解决S3Client优先读取本地凭证而非.env配置的问题
问题场景
Node.js项目使用@aws-sdk/client-s3存储媒体文件到S3 Bucket,已在项目根目录配置.env文件:
AWS_ACCESSKEYID = AHMXXXXXXXXXXH AWS_SECRETKEY = fdgggdgdmcxvxcvbvfdgffgfs AWS_REGION = ap-south-1
S3客户端初始化代码如下:
const { S3Client, PutObjectCommand, DeleteObjectCommand, HeadObjectCommand } = require('@aws-sdk/client-s3') const s3 = new S3Client({ accessKeyId: config.AWS_ACCESSKEYID, secretAccessKey: config.AWS_SECRETKEY, signatureVersion: 'v4', region: config.AWS_REGION })
但实际运行时,S3Client仍尝试加载本地AWS CLI的~/.aws/credentials凭证,且抛出错误:
CredentialsProviderError: Could not load credentials from any providers at /node_modules/@aws-sdk/credential-provider-node/dist-cjs/defaultProvider.js:13:11 at /node_modules/@smithy/property-provider/dist-cjs/chain.js:12:39 at processTicksAndRejections (node:internal/process/task_queues:96:5) at async coalesceProvider ( /node_modules/@smithy/property-provider/dist-cjs/memoize.js:14:24) at async SignatureV4.credentialProvider ( /node_modules/@smithy/property-provider/dist-cjs/memoize.js:33:24) at async SignatureV4.signRequest ( /node_modules/@smithy/signature-v4/dist-cjs/SignatureV4.js:106:29) at async /node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:16:18 at async /node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46 at async /node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-endpoint-middleware.js:14:24 at async /node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-middleware.js:9:20 {
需要调整配置,让S3Client仅使用.env中的凭证。
解决方案
1. 修复.env文件格式与变量名
AWS SDK默认识别的环境变量名是AWS_ACCESS_KEY_ID和AWS_SECRET_ACCESS_KEY,同时要去掉变量值前后的空格(避免解析错误):
AWS_ACCESS_KEY_ID=AHMXXXXXXXXXXH AWS_SECRET_ACCESS_KEY=fdgggdgdmcxvxcvbvfdgffgfs AWS_REGION=ap-south-1
2. 确保.env变量正确加载
在项目入口文件(如app.js)顶部添加dotenv加载逻辑,确保环境变量被注入到process.env:
require('dotenv').config();
3. 修改S3Client初始化代码,强制使用指定凭证
显式通过credentials对象传入凭证,而非直接在根级别传accessKeyId和secretAccessKey,同时可选禁用默认凭证链:
const { S3Client, PutObjectCommand, DeleteObjectCommand, HeadObjectCommand } = require('@aws-sdk/client-s3'); // 从process.env读取凭证,确保无多余空格 const accessKeyId = process.env.AWS_ACCESS_KEY_ID.trim(); const secretAccessKey = process.env.AWS_SECRET_ACCESS_KEY.trim(); const region = process.env.AWS_REGION; const s3 = new S3Client({ region: region, // 显式指定凭证对象 credentials: { accessKeyId: accessKeyId, secretAccessKey: secretAccessKey }, // 可选:自定义凭证提供者,彻底跳过默认凭证链 credentialProvider: async () => ({ accessKeyId, secretAccessKey }) });
原理说明
- 旧代码直接在S3Client构造函数根级别传
accessKeyId和secretAccessKey时,AWS SDK仍会优先遍历默认凭证链(本地CLI凭证、IAM角色等),当链中凭证无效时抛出错误。 - 显式传入
credentials对象后,SDK会优先使用该凭证;配合自定义credentialProvider可彻底跳过默认凭证链,强制使用指定的.env凭证。
内容的提问来源于stack exchange,提问作者Ravi Kyada
相关产品推荐
相关产品推荐

