在具有 Elixir/Phoenix 后端的 React Native 应用程序中,我试图让用户创建一张照片,该照片将使用 AWS 预签名 URL 推送到 S3 存储桶。我正在使用 Hex 包 ex_aws 来公开 API。虽然我对 Elixir 比较陌生,但我遵循了文档,并且代码生成了上传 url,没有任何问题。
配置:
config :ex_aws,
access_key_id: System.get_env("AWS_ACCESS_KEY_ID"),
secret_access_key: System.get_env("AWS_SECRET_ACCESS_KEY"),
s3: [
scheme: "https://",
host: "my-bucket.s3.amazonaws.com",
region: "us-east-1"
]
生成上传URL的函数:
def get_presign_url do
uuid = UUID.uuid4()
bucket = "photos"
config = %{region: "us-east-1"}
query_params = [{"ContentType", "image/jpeg"}, {"ACL", "public-read"}]
presign_options = [virtual_host: false, query_params: query_params]
{:ok, url} =
ExAws.Config.new(:s3, config)
|> ExAws.S3.presigned_url(:put, bucket, "#{uuid}.jpg", presign_options)
%{upload_url: url, url: get_image_url(bucket, uuid)}
end
defp get_image_url(bucket, uuid) do
"http://s3.amazonaws.com/my-bucket/#{bucket}/#{uuid}.jpg"
end
并作为对象添加到类型中:
object :presign_url do
field(:url, non_null(:string))
field(:upload_url, non_null(:string))
end
我正在使用用 Absinthe 实现的 GraphQL,我已添加到解析器中,如下所示:
def presign_url(_, _, _) do
{:ok, Server.Posts.get_presign_url()}
end
这是生成的上传 URL:
{
"data": {
"presignUrl": {
"url": "http://s3.amazonaws.com/my-bucket/photos/3c55bf4c- cc9f-4ef4-bb53-f7b4190594e1.jpg",
"uploadUrl": "https://my-bucket.s3.amazonaws.com/photos/3c55bf4c- cc9f-4ef4-bb53-f7b4190594e1.jpg?ACL=public-read&ContentType=image%2Fjpeg&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIELM4UKGWPA4JINA%2F20180707%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20180707T192017Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=acl%3Bcontenttype%3Bhost&X-Amz-Signature=f731765ccc12dc497050acf9578dcd375116b75a73cf4069beb6c3a46ed37535"
}
}
}
这些也是构成 ex_awspackage 的服务:
{:ex_aws, "~> 2.0"},
{:ex_aws_s3, "~> 2.0"},
{:hackney, "~> 1.9"},
{:sweet_xml, "~> 0.6"},
我创建了一个附加了 AmazonS3FullAccess 策略的 IAM 用户。我还尝试使用具有完全管理权限且 S3 存储桶完全公开的 IAM 用户发送图像。我尝试过使用和不使用 UUID,并尝试在查询参数中删除内容类型。密钥和访问密钥导出到 .env 文件中,我检查了它们是否与 AWS 匹配,并检查了是否存在任何空白错误。我确保了 .env 文件的来源。我还尝试将密钥直接添加到 Postman 中的授权类型中。最后,我两次删除并重新创建了 IAM 用户和 S3 存储桶,但均无济于事。使用指定的 Put 方法,这是返回:
<?xml version="1.0" encoding="UTF-8"?>
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>The request signature we calculated does not match the signature you provided. Check your key and signing method. </Message>
<AWSAccessKeyId><MyAccessKey></AWSAccessKeyId>
<StringToSign>AWS4-HMAC-SHA256
20180707T192017Z
20180707/us-east-1/s3/aws4_request
20d99c7ca8361bdf1a22207490e60f15a24181dbb1a6f3242a5a6fc99580bbf6</StringTo Sign>
<SignatureProvided>f731765ccc12dc497050acf9578dcd375116b75a73cf4069beb6c3a46ed37535"</SignatureProvided>
<StringToSignBytes>41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 0a 32 30 31 38 30 37 30 37 54 31 39 32 30 31 37 5a 0a 32 30 31 38 30 37 30 37 2f 75 73 2d 65 61 73 74 2d 31 2f 73 33 2f 61 77 73 34 5f 72 65 71 75 65 73 74 0a 32 30 64 39 39 63 37 63 61 38 33 36 31 62 64 66 31 61 32 32 32 30 37 34 39 30 65 36 30 66 31 35 61 32 34 31 38 31 64 62 62 31 61 36 66 33 32 34 32 61 35 61 36 66 63 39 39 35 38 30 62 62 66 36</StringToSignBytes>
<CanonicalRequest>PUT
/photos/3c55bf4c-cc9f-4ef4-bb53-f7b4190594e1.jpg
ACL=public-read&ContentType=image%2Fjpeg&X-Amz-Algorithm=AWS4- HMAC-SHA256&X-Amz-Credential=AKIAIELM4UKGWPA4JINA%2F20180707%2Fus-`enter code here`east-1%2Fs3%2Faws4_request&X-Amz-Date=20180707T192017Z&X-Amz-Expires=3600&X-Amz-SignedHeaders=acl%3Bcontenttype%3Bhost
acl:
contenttype:
host:my-bucket.s3.amazonaws.com
acl;contenttype;host
UNSIGNED-PAYLOAD</CanonicalRequest>
<CanonicalRequestBytes>50 55 54 0a 2f 70 68 6f 74 6f 73 2f 33 63 35 35 62 66 34 63 2d 63 63 39 66 2d 34 65 66 34 2d 62 62 35 33 2d 66 37 62 34 31 39 30 35 39 34 65 31 2e 6a 70 67 0a 41 43 4c 3d 70 75 62 6c 69 63 2d 72 65 61 64 26 43 6f 6e 74 65 6e 74 54 79 70 65 3d 69 6d 61 67 65 25 32 46 6a 70 65 67 26 58 2d 41 6d 7a 2d 41 6c 67 6f 72 69 74 68 6d 3d 41 57 53 34 2d 48 4d 41 43 2d 53 48 41 32 35 36 26 58 2d 41 6d 7a 2d 43 72 65 64 65 6e 74 69 61 6c 3d 41 4b 49 41 49 45 4c 4d 34 55 4b 47 57 50 41 34 4a 49 4e 41 25 32 46 32 30 31 38 30 37 30 37 25 32 46 75 73 2d 65 61 73 74 2d 31 25 32 46 73 33 25 32 46 61 77 73 34 5f 72 65 71 75 65 73 74 26 58 2d 41 6d 7a 2d 44 61 74 65 3d 32 30 31 38 30 37 30 37 54 31 39 32 30 31 37 5a 26 58 2d 41 6d 7a 2d 45 78 70 69 72 65 73 3d 33 36 30 30 26 58 2d 41 6d 7a 2d 53 69 67 6e 65 64 48 65 61 64 65 72 73 3d 61 63 6c 25 33 42 63 6f 6e 74 65 6e 74 74 79 70 65 25 33 42 68 6f 73 74 0a 61 63 6c 3a 0a 63 6f 6e 74 65 6e 74 74 79 70 65 3a 0a 68 6f 73 74 3a 73 61 67 61 2d 62 65 74 61 2e 73 33 2e 61 6d 61 7a 6f 6e 61 77 73 2e 63 6f 6d 0a 0a 61 63 6c 3b 63 6f 6e 74 65 6e 74 74 79 70 65 3b 68 6f 73 74 0a 55 4e 53 49 47 4e 45 44 2d 50 41 59 4c 4f 41 44</CanonicalRequestBytes>
<RequestId>217EC822CDAB80C8</RequestId>
<HostId>m39utFRVAH61JVNNeYPET1ztudrRWy3qsaIGHl9lh5/2Arjfr1L+EcZ3S8UDqcOEB3hIAP5pMOM=</HostId>
</Error>
我相信AWS方面一定存在权限问题,我根本没有看到,但是我已经浏览了文档,但我找不到任何东西,第二天继续使用这个,非常感谢任何帮助。