我似乎无法正确获得身份验证。
我已经创建了在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'
}
}
}
答案 0 :(得分:1)
在执行aws.config.update()
之前,您应使用凭据 调用s3 = new aws.S3()
。否则,配置更新将不会绑定到S3对象,并且将使用默认的凭据链。
还要确保访问密钥和秘密密钥正确,但是我认为这不是问题所在。