vue-s3-dropzone icon indicating copy to clipboard operation
vue-s3-dropzone copied to clipboard

Could you elaborate on the AWS API Gateway?

Open chopfitzroy opened this issue 7 years ago • 7 comments

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.

chopfitzroy avatar Mar 10 '17 20:03 chopfitzroy

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.

fibble avatar Mar 15 '17 10:03 fibble

Thank you these will be super helpful will hopefully get to integrating over the weekend ☺️

chopfitzroy avatar Mar 15 '17 18:03 chopfitzroy

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.

fibble avatar Mar 15 '17 19:03 fibble

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.

scofield-ua avatar Jan 19 '18 11:01 scofield-ua

I think it will be a good idea to merge this issue to the documentation.

sfdye avatar Feb 28 '18 07:02 sfdye

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).

mahmoudmahdi24 avatar Jun 06 '18 13:06 mahmoudmahdi24

For me var bucketName = process.env.AWS_BUCKET_NAME was not morking for some readon. So I entered just bucketName=AWS_BUCKET_NAME.

kasper747 avatar Aug 31 '18 15:08 kasper747