【发布时间】: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