使用Node.js V3 SDK连接S3 Bucket的凭证配置及证书问题
AWS SDK V3 连接S3 Bucket 凭证及证书问题解决
问题场景
- 使用NodeJS + AWS SDK V3上传文本到S3 Bucket时,抛出
CredentialsProviderError: Could not load credentials from any providers异常 - 尝试通过
~/.aws/credentials配置凭证后,出现Error: unable to verify the first certificate错误
错误原因及解决方案
一、「缺少凭证提供者」问题解决
AWS SDK V3的S3Client配置中,凭证参数不能直接放在配置根节点,需要嵌套在credentials对象中;或者使用SDK默认的凭证链加载方式(比如读取~/.aws/credentials)。
修正代码(直接传入凭证)
将原代码中的bucketProps修改为:
const bucketProps = { region: 'us-east-1', endpoint: endPoint, credentials: { accessKeyId: 'qys4ddggd', secretAccessKey: 'mysecretkryvalie' } }
注意:Bucket不需要写在S3Client的配置里,只需要在PutObjectCommand中指定即可。
使用~/.aws/credentials加载凭证
如果想用本地凭证文件,不需要在代码中硬编码凭证,SDK会自动读取~/.aws/credentials文件,此时S3Client配置可以简化为:
const bucketProps = { region: 'us-east-1', endpoint: endPoint }
确保~/.aws/credentials文件格式正确(无多余空格,替换占位符):
[default] aws_access_key_id = 你的AccessKeyId aws_secret_access_key = 你的SecretAccessKey
二、「证书验证失败」问题解决
这个错误通常是因为你连接的S3兼容存储使用了自签名证书,或者endpoint是HTTP协议但SDK默认尝试HTTPS连接(如果是自定义HTTP endpoint,需要显式配置)。
方案1:关闭证书验证(仅开发环境使用)
在S3Client配置中添加tls: { rejectUnauthorized: false }:
const bucketProps = { region: 'us-east-1', endpoint: endPoint, credentials: { accessKeyId: 'qys4ddggd', secretAccessKey: 'mysecretkryvalie' }, tls: { rejectUnauthorized: false } }
方案2:指定自定义CA证书(生产环境推荐)
如果是自签名证书,可以将CA证书文件路径配置到SDK中:
import fs from 'fs'; const caCert = fs.readFileSync('./path/to/your/ca.crt'); const bucketProps = { region: 'us-east-1', endpoint: endPoint, credentials: { accessKeyId: 'qys4ddggd', secretAccessKey: 'mysecretkryvalie' }, tls: { ca: caCert } }
方案3:确保endpoint协议正确
如果你连接的是HTTP服务,需要在EndpointV2的url中明确使用http://,并且SDK默认会根据url协议处理,确认你的自定义S3服务确实使用HTTP而非HTTPS。
完整修正后的代码示例
import connProperties from "./myprops"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { EndpointV2 } from '@aws-sdk/types'; const connect = async () => { if (connProperties.isValidProps()) { const endPoint: EndpointV2 = { url: new URL('http://my-s3-bucket-site.com') } as EndpointV2; const bucketProps = { region: 'us-east-1', endpoint: endPoint, credentials: { accessKeyId: 'qys4ddggd', secretAccessKey: 'mysecretkryvalie' }, tls: { rejectUnauthorized: false // 仅开发环境使用 } }; const command = new PutObjectCommand({ Bucket: 'data-log', Key: "test-s3.txt", Body: "This is some text!", }); const s3client = new S3Client(bucketProps); try { await s3client.send(command); // 记得添加await,否则不会等待上传完成 console.log('文件上传成功'); } catch (err) { console.error('上传失败:', err); } } else { console.log('Cannot send to S3 Bucket'); } }
注意:s3client.send(command)是异步操作,需要添加await并包裹在try/catch中捕获异常。
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

