尝试上传到 AWS S3 时无法从任何提供商加载凭证 [英] Could not load credentials from any providers when attempting upload to AWS S3

查看:59
本文介绍了尝试上传到 AWS S3 时无法从任何提供商加载凭证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我似乎无法正确验证身份.

I can't seem to get the auth correct.

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

I've created the buckets in use on AWS S3.

我在两个 AWS 上都创建了访问密钥和秘密,并按照指定在 Heroku 上将它们作为环境变量输入 此处.

I've created access key and secret on both AWS and entered them as environment variables on Heroku as specified here.

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

I've verified that access key is visible in config log.

我错过了什么?

我目前正在本地主机上尝试此操作,因此我手动更新配置,但稍后我希望服务器代码在 Heroku 上运行.

I'm currently trying this on localhost hence the condition where I update the config manually, but later on I want the server code to run on 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 之前 使用凭据调用 aws.config.update()= 新的 aws.S3().否则,配置更新不会绑定到 S3 对象,它将使用默认凭据链.

You should invoke aws.config.update() with the credentials before executing s3 = new aws.S3(). The config update will not bind to the S3 object otherwise, and it will use the default credentials chain.

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

Also make sure that the access key and secret key are correct, but I don't think that's the issue here.

这篇关于尝试上传到 AWS S3 时无法从任何提供商加载凭证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆