Open chopfitzroy opened 7 years ago
Hi.
Ive just got this working - took some time and some playing about but this was roughly my workflow:
Create new lamda function using the code from this repository. Start with a blank function, Nodejs 4.3 and paste it in.
for Role choose Create New role and paste in this template modifying the bucket name as appropriate:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": [
"arn:aws:s3:::<YOUR_BUCKET_NAME>/*"
]
}
]
}
Make sure you attach an API Gateway trigger. Then head over to the API Gateway section for the rest of the configuration.
I created a POST method. Then i had to create a usage plan. Associated the usage plan with the prod stage of the API and generate an API Key for the usage plan.
I edited the POST method and set "Auth" to none and "API key required" to true. I had to untick "Use Lambda Proxy integration" in Method Execution.
Config screenshot 1 Config Screenshot 2
I enabled CORS here also with permissive defaults.
Make sure you Deploy the API to /prod (or whatver your stage was named) after any edits before you try hitting the URL.
Finally in the S3 bucket configuration i used this CORS Policy:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>PUT</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
I was then able to use POSTman/Insomnia to hit the /prod/getSignedUrl endpoint with a POST request, with an x-api-key header set to the API key generated for the usage plan.
Heres a curl example of how i hit the API to get a signed URL that worked fine to PUT a file direct to S3:
curl --request POST \
--url https://myendpoint.execute-api.eu-west-1.amazonaws.com/prod/getSignedUrl \
--header 'x-api-key: YOURAPIKEY' \
--data '{
"filePath": "filename.txt",
"contentType": "mime/type"
}'
Apologies for the somewhat chaotic / incomplete instructions. I spent some time getting it to work and this is a memory dump of what was actually important :) If you hit any issues i can attempt to answer based on my now working setup.
Thank you these will be super helpful will hopefully get to integrating over the weekend ☺️
Worth noting that if you require an API Key in API Gateway config will need a tweak to the frontend JS code to include it as an x-api-key header. If your happy with open access to the lamda function for public upload you can set API Key Required False. My app this is not acceptable and i want all PUTs to only come from authorized clients.
Hi @fibble. Can you share your S3 bucket policy config? How can we allow PUT only for pre-signed action (don't know how to call it right).
Something like this:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "",
"Action": [
"s3:PutObject",
"s3:PutObjectAcl"
],
"Resource": "arn:aws:s3:::bucket-name/*"
}
]
}
But I can't get what should I specify on Principal
line.
I think it will be a good idea to merge this issue to the documentation.
For the ones facing CORS issues with this, follow @fibble instructions and then modify the "API Responses" to add "allow-access-control-origin" in the responses (of the options and the post method).
For me var bucketName = process.env.AWS_BUCKET_NAME
was not morking for some readon. So I entered just bucketName=AWS_BUCKET_NAME
.
Hey I am a little new to the AWS stuff and I would like to know the purpose of the API Gateway?
I am currently working on an electron application and trying to figure out how I can securely use AWS Lambda (i.e where do I store my AWS credentials etc...) I am thinking I may need to set up a proxy service that will hold the AWS credentials on the server side?
But I am wondering if the API Gateway is intended to cover this?
Cheers.