const AWS = require('aws-sdk');
export function main (event, context, callback) {
const s3 = new AWS.S3();
const data = JSON.parse(event.body);`
const s3Params = {
Bucket: process.env.mediaFilesBucket,
Key: data.name,
ContentType: data.type,
ACL: 'public-read',
};
const uploadURL = s3.getSignedUrl('putObject', s3Params);
callback(null, {
statusCode: 200,
headers: {
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({ uploadURL: uploadURL }),
})
}
当我在本地对其进行测试时,它可以很好地工作,但是在部署它后,它会发出x-amz-security-token令牌,然后出现拒绝访问的响应。如何摆脱这个x-amz-security-token?
答案 0 :(得分:1)
我刚刚解决了一个非常相似的问题,可能与您遇到的问题相同。我说这可能是因为您没有说要进行什么部署。我假设您正在部署到Lambda,但可能并不适用,这可能适用或可能不适用,但是如果您使用的是临时凭据,则将适用。
我最初使用的是您上面使用的方法,但是后来使用了npm模块aws-signature-v4来查看它是否不同并得到与您相同的错误。
您将需要令牌,当您使用临时凭据签署请求时就需要令牌。在Lambda的情况下,凭据位于运行时中,包括您需要传递的会话令牌,其他地方也很可能同样如此,但是我不确定几年内没有使用过ec2。
埋在文档中(很抱歉,我找不到在此声明的地方),指出某些服务要求session_token与其他规范查询参数一起处理。正如sig v4指令所暗示的那样,我正在使用的模块最后添加了它,因此我对其进行了修改,使令牌具有规范性并可以正常工作。
我们已经更新了aws-signature-v4模块的实时版本以反映此更改,现在它可以很好地用于签署s3请求。
我会使用我做过的模块,因为我感觉到sdk出于某种原因做错了事。
使用示例(此文件包装在multiPart上传文件中,因此包含零件编号和上传ID):
function createBaseUrl( bucketName, uploadId, partNumber, objectKey ) {
let url = sig4.createPresignedS3URL( objectKey, {
method: "PUT",
bucket: bucketName,
expires: 21600,
query: `partNumber=${partNumber}&uploadId=${uploadId}`
});
return url;
}
答案 1 :(得分:0)
我遇到了同样的问题。使用serverless-offline
一切都可以正常工作,但是当我部署到Lambda时,我开始在URL上收到AccessDenied
问题。比较serverless-offline
与AWS部署之间返回的URL时,我注意到唯一的区别是URL中包含了X-Amz-Security-Token
作为查询字符串参数。经过一番挖掘后,我发现分配的令牌是基于lambda函数具有的假定角色。我要做的就是为该角色授予适当的S3策略,并且该策略有效。
答案 2 :(得分:0)
我遇到了同样的问题,我正在使用Python3.7中的库Boto3创建一个签名的URL
尽管这不是建议的解决方法,但它对我有用。
请求方法应为POST,content-type = ['multipart / form-data']
以这种方式创建客户端。
# Do not hard code credentials
client = boto3.client(
's3',
# Hard coded strings as credentials, not recommended.
aws_access_key_id='YOUR_ACCESS_KEY',
aws_secret_access_key='YOUR_SECRET_ACCESS_KEY'
)
返回响应
bucket_name = BUCKET
acl = {'acl': 'public-read-write'}
file_path = str(file_name) //file you want to upload
response = s3_client.generate_presigned_post(bucket_name,
file_path,
Fields={"Content-Type": ""},
Conditions=[acl,
{"Content-Type": ""},
["starts-with", "$success_action_status", ""],
],
ExpiresIn=3600)