【问题标题】:Could not load credentials from any providers when attempting upload to AWS S3尝试上传到 AWS S3 时无法从任何提供商加载凭证
【发布时间】:2019-10-02 19:06:03
【问题描述】:

我似乎无法获得正确的身份验证。

我已经创建了在 AWS S3 上使用的存储桶。

我已经在两个 AWS 上创建了访问密钥和秘密,并将它们作为指定 here 的 Heroku 上的环境变量输入。

我已验证访问密钥在配置日志中可见。

我错过了什么?

我目前正在 localhost 上尝试此操作,因此我手动更新配置的条件是,但稍后我希望服务器代码在 Heroku 上运行。

客户端:

   async upload(adId: string, file: File) {
        const url = this.baseUrl + `api/image/${adId}`
        const fileName = this.createUniqueFileName(adId, file)
        const data = { fileName: fileName, fileType: file.type }
        const response = await axios.post(url, data, { headers: { 'Content-Type': 'application/json' } }) // Fetch a signed AWS S3 url from ad-keeper
        const formData = new FormData()
        formData.append(fileName, file)
        const awsS3Response = await axios.put(response.data.signedUrl, formData, { headers: { 'Content-Type': 'multipart/form-data' } }) // Upload file to AWS S3 bucket
        return awsS3Response.status === 200
    }

服务器端:

   app.post('/api/image/:adId', (request, response) => {
        const s3 = new aws.S3()
        if (request.headers.host.includes('localhost')) {
            aws.config.update({ region: localHostAwsConfig.region, accessKeyId: localHostAwsConfig.accessKeyId, secretAccessKey: localHostAwsConfig.secretAccessKey })
        }
        const fileName = request.body.fileName
        const fileType = request.body.fileType
        const bucketName = process.env.AWS_S3_BUCKET_NAME || "localhost-bucket"
        const params = {
            Bucket: bucketName,
            Key: fileName,
            Expires: 60,
            ContentType: fileType,
            ACL: 'public-read'
        }
        console.log(aws.config)
        s3.getSignedUrl('putObject', params, (error, data) => {
            if (error) {
                console.log(error)
                return response.status(500).end() // Server call ends up here
            }
            const imageUrl = `https://${bucketName}.s3.amazonaws.com/${fileName}`
            adSource.setImageUrl(request.params.adId, imageUrl)
            return response.json({ signedRequest: data, imageUrl: imageUrl })
        });
    });

打印配置:

Config {
  credentials: Credentials {
    expired: false,
    expireTime: null,
    refreshCallbacks: [],
    accessKeyId: '<ACCESS_KEY>',
    sessionToken: undefined
  },
  credentialProvider: CredentialProviderChain {
    providers: [
      [Function],
      [Function],
      [Function],
      [Function],
      [Function],
      [Function]
    ],
    resolveCallbacks: []
  },
  region: 'eu-north-1',
  logger: null,
  apiVersions: {},
  apiVersion: null,
  endpoint: undefined,
  httpOptions: { timeout: 120000 },
  maxRetries: undefined,
  maxRedirects: 10,
  paramValidation: true,
  sslEnabled: true,
  s3ForcePathStyle: false,
  s3BucketEndpoint: false,
  s3DisableBodySigning: true,
  computeChecksums: true,
  convertResponseTypes: true,
  correctClockSkew: false,
  customUserAgent: null,
  dynamoDbCrc32: true,
  systemClockOffset: 0,
  signatureVersion: null,
  signatureCache: true,
  retryDelayOptions: {},
  useAccelerateEndpoint: false,
  clientSideMonitoring: false,
  endpointDiscoveryEnabled: false,
  endpointCacheSize: 1000,
  hostPrefixEnabled: true
}

打印错误:

Error: connect ETIMEDOUT 169.254.169.254:80
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1054:14) {
  message: 'Missing credentials in config',
  errno: 'ETIMEDOUT',
  code: 'CredentialsError',
  syscall: 'connect',
  address: '169.254.169.254',
  port: 80,
  time: 2019-05-15T15:11:01.789Z,
  originalError: {
    message: 'Could not load credentials from any providers',
    errno: 'ETIMEDOUT',
    code: 'CredentialsError',
    syscall: 'connect',
    address: '169.254.169.254',
    port: 80,
    time: 2019-05-15T15:11:01.789Z,
    originalError: {
      errno: 'ETIMEDOUT',
      code: 'ETIMEDOUT',
      syscall: 'connect',
      address: '169.254.169.254',
      port: 80,
      message: 'connect ETIMEDOUT 169.254.169.254:80'
    }
  }
}

【问题讨论】:

  • 使用凭据执行 s3 = new aws.S3() 调用 aws.config.update()。并确保访问密钥和密钥是您所期望的。
  • @jarmod 谢谢,那行得通。把它放在一个答案中,我会接受它。

标签: node.js amazon-web-services heroku amazon-s3 aws-sdk-nodejs


【解决方案1】:

您应该在执行s3 = new aws.S3() 之前 使用凭据调用aws.config.update()。否则配置更新不会绑定到 S3 对象,它将使用默认凭据链。

还要确保访问密钥和密钥正确,但我认为这不是问题所在。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-17
    • 2017-06-15
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-11
    • 2019-06-20
    相关资源
    最近更新 更多