kfei / vue-s3-dropzone

:droplet: Vue.js component works with AWS S3 serverlessly
455 stars 68 forks source link

Could you elaborate on the AWS API Gateway? #2

Open chopfitzroy opened 7 years ago

chopfitzroy commented 7 years ago

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.

fibble commented 7 years ago

Hi.

Ive just got this working - took some time and some playing about but this was roughly my workflow:

{
  "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.

chopfitzroy commented 7 years ago

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

fibble commented 7 years ago

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.

scofield-ua commented 6 years ago

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.

sfdye commented 6 years ago

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

mahmoudmahdi24 commented 6 years ago

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

kasper747 commented 6 years ago

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