【发布时间】:2018-07-20 10:15:21
【问题描述】:
我编写了一个 lambda 函数,它为 S3 存储桶中的文档返回一个预签名的 url。
代码真的很简单:
const url = s3.getSignedUrl('getObject', {
Bucket: BUCKET_NAME,
Key: myFile.Key,
Expires: 20
})
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Origin": "*"
},
body: JSON.stringify({
"url": url
}),
};
有趣的是,当我像这样在本地(使用无服务器框架)调用此函数时:
sls invoke local -f getEconomyFile -d '{ "queryStringParameters": { "key": "myfile.pdf" } }'
它正在工作!我有一个给我文件的网址。
但是当我部署到 AWS Lambda 时,该函数返回一个 URL,该 URL 总是在文件上显示“访问被拒绝”:
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>93778EA364B3506B</RequestId>
<HostId>
yqnPC0SeIVE3/Pl7/d+xHDJ78=
</HostId>
</Error>
为什么它在本地工作而不是部署?
谢谢!
【问题讨论】:
-
您的签名 URL 在生成 20 秒后过期。有没有可能它只是过期了?默认为 15m。
-
不,我试图删除 Expires 参数,但不是这样:-/
-
Lambda 函数使用的 IAM 角色实际上是否允许 S3 GetObject 访问相关存储桶?预签名 URL 生成本身不会对 afaik 凭据进行任何验证。如果不是这样,那么我会检查预签名的 URL 是否以某种方式损坏,并且您的客户端是否已进行时间同步。
-
似乎不是这样,在我的无服务器文件配置中:iamRoleStatements: - 效果:允许操作:s3:* 资源:arn:aws:s3:::BUCKET-NAME。
-
您还需要通过 arn:aws:s3:::BUCKET-NAME/* 获得对象权限
标签: amazon-web-services aws-lambda serverless-framework