{"id":17601261,"url":"https://github.com/sam-martin/aws-image-upload-without-ec2","last_synced_at":"2025-04-30T07:49:40.869Z","repository":{"id":80868796,"uuid":"41624488","full_name":"Sam-Martin/aws-image-upload-without-ec2","owner":"Sam-Martin","description":null,"archived":false,"fork":false,"pushed_at":"2015-08-30T14:01:37.000Z","size":220,"stargazers_count":40,"open_issues_count":1,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-30T07:49:35.058Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Sam-Martin.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-30T10:22:45.000Z","updated_at":"2024-12-17T09:40:15.000Z","dependencies_parsed_at":"2023-03-12T12:38:52.051Z","dependency_job_id":null,"html_url":"https://github.com/Sam-Martin/aws-image-upload-without-ec2","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sam-Martin%2Faws-image-upload-without-ec2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sam-Martin%2Faws-image-upload-without-ec2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sam-Martin%2Faws-image-upload-without-ec2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Sam-Martin%2Faws-image-upload-without-ec2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Sam-Martin","download_url":"https://codeload.github.com/Sam-Martin/aws-image-upload-without-ec2/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251666226,"owners_count":21624290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-22T12:09:18.699Z","updated_at":"2025-04-30T07:49:40.846Z","avatar_url":"https://github.com/Sam-Martin.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# AWS Image Upload Without EC2 Example  \n [![GitHub license](https://img.shields.io/github/license/Sam-Martin/servicenow-powershell.svg)](LICENSE) [![Build Status](https://travis-ci.org/X0nic/chef-snapraid.svg)](https://travis-ci.org/sam-martin/aws-image-upload-without-ec2)  \nThis repository contains the Node.js, HTML, JavaScript, and supporting jQuery plugins to upload images securely to S3 using [Amazon API Gateway](https://aws.amazon.com/api-gateway/) and [AWS Lambda](https://aws.amazon.com/lambda/) to generate a [signed upload url](http://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html).  \n## Demo\nYou can find a demo online at [ImageUpload.SamMart.in](http://imageupload.sammart.in/) (images are deleted automatically almost immediately).\n## Overview\nThis example project is simply an exercise for me (Sam Martin) to dabble in:\n\n1. AWS Lambda  \n2. Amazon API Gateway  \n3. Basic CSS, JS, and HTML linting with [Travis CI](https://travis-ci.org/)    \n\nThe execution workflow is extremely simple. From loading the page in the browser: \n\n1. User selects a file to upload \n2. JavaScript calls out to the API Gateway endpoint using jQuery's `$.post` to retrieve a signed upload URL  \n3. API Gateway calls the Lambda Node.js script  \n4. Node.js script assumes the IAM role associated with it which has permission to upload an object to the s3 bucket  \n5. Node.js uses the inbuilt AWS SDK to `getSignedUrl` and returns it in its `context.done`  \n6. This url is returned to the client-side JS via API Gateway and is then used to upload a file using [BlueImp's jQuery File Upload](https://github.com/blueimp/jQuery-File-Upload)  \n\n## Future and Alternatives\nAfter whipping up this example I discovered it was actually possible to do this using signed url *policies* (I didn't previously appreciate that the signature validated the policy).  \nThis removes the need to involve either Lambda or the API Gateway ([more info here](https://aws.amazon.com/articles/1434), [JS example here](http://stackoverflow.com/questions/11240127/uploading-image-to-amazon-s3-with-html-javascript-jquery-with-ajax-request-n/12378395#12378395)), and actually provides [more functionality](http://stackoverflow.com/questions/29550537/how-to-set-content-length-range-for-s3-browser-upload-via-boto).  \nHowever, this was still a useful learning experience, and with this methodology you are able to maintain control over the key name, which you aren't with the above example. (Though admittedly not being able to control the max upload size server side is a pretty big downside!)  \nI also want to add in support for user authentication at some point using [Amazon Cognito](https://aws.amazon.com/cognito/) which will make better use of the API Gateway and Lambda services.\n\n## Plugins \u0026 Frameworks\n* [BlueImp's jQuery File Upload](https://github.com/blueimp/jQuery-File-Upload) for uploading\n* [Twitter BootStrap](http://getbootstrap.com/) for styling\n* [AWS SDK](https://aws.amazon.com/sdk-for-node-js/) (built into Node.js)\n* [JSHint](https://www.npmjs.com/package/jshint) for JavScript linting\n* [PrettyCSS](https://www.npmjs.com/package/PrettyCSS) for CSS linting\n\n## Continuous Integration\nThe continuous integration portion of this dabbling is currently limited to JS and CSS linting using `JSHint` and `PrettyCSS` respectively.\n\n## Usage\nToDo\n\n## Permissions\n### Node.js role\n```\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"Stmt1440938489000\",\n            \"Effect\": \"Allow\",\n            \"Action\": [\n                \"s3:PutObject\"\n            ],\n            \"Resource\": [\n                \"arn:aws:s3:::image-upload-smartin\",\n                \"arn:aws:s3:::image-upload-smartin/*\"\n            ]\n        }\n    ]\n}\n```\n### S3 Bucket  CORS Configuration\n```\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003cCORSConfiguration xmlns=\"http://s3.amazonaws.com/doc/2006-03-01/\"\u003e\n    \u003cCORSRule\u003e\n        \u003cAllowedOrigin\u003e*\u003c/AllowedOrigin\u003e\n        \u003cAllowedMethod\u003ePUT\u003c/AllowedMethod\u003e\n        \u003cAllowedMethod\u003ePOST\u003c/AllowedMethod\u003e\n        \u003cAllowedMethod\u003eGET\u003c/AllowedMethod\u003e\n        \u003cAllowedMethod\u003eHEAD\u003c/AllowedMethod\u003e\n        \u003cMaxAgeSeconds\u003e3000\u003c/MaxAgeSeconds\u003e\n        \u003cAllowedHeader\u003e*\u003c/AllowedHeader\u003e\n    \u003c/CORSRule\u003e\n\u003c/CORSConfiguration\u003e\n\n```\n### S3 Bucket Policy\n```\n{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Sid\": \"PublicReadGetObject\",\n            \"Effect\": \"Allow\",\n            \"Principal\": \"*\",\n            \"Action\": \"s3:GetObject\",\n            \"Resource\": \"arn:aws:s3:::image-upload-smartin/*\"\n        }\n    ]\n}\n```\n## Author\nAuthor:: Sam Martin (\u003csamjackmartin@gmail.com\u003e)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsam-martin%2Faws-image-upload-without-ec2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsam-martin%2Faws-image-upload-without-ec2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsam-martin%2Faws-image-upload-without-ec2/lists"}