Signed Download URLs
In the previous chapter, you used the same URL for both the form display function and the form processing function. This was possible because the browser web form workflow used two different HTTP methods. To display the form, it sent a GET request. To upload the submission details, it sent a POST request. Because S3 redirects work as GET method calls, you cannot use the same URL with different methods anymore. The browser will send a POST request directly to S3, which will redirect to another URL. You’ll need a different URL to handle that redirect, so you can create a new API endpoint.
When S3 sends a redirect after the upload, it will include information about the uploaded file in the query string. This allows you to do some post-processing on the uploaded file or to let the users access it. To keep things simple for now, just allow users to download a file they uploaded. In theory, you could read the file out using a Lambda function and send it back through API Gateway. By now, though, you know that there is a better way to handle that.
S3 can serve public files directly to browsers. For example, public files in a bucket called
testbucket in the
us-east-1 region will be accessible directly from
https://testbucket.s3.amazonaws.com. For other regions, the second URL component is
s3- followed by the region (for example
https://testbucket.s3-eu-west-1.amazonaws.com). Letting users download files is a great option if you don’t care about protecting read access, for example if you are making a public gallery. To upload publicly readable files, just change the access control list in the upload policy from
public-read (line 19 in
To tightly control who can read the uploaded files, instead of a public link you can pre-sign a download request. A signed download request effectively provides a temporary grant to access a particular file on S3 directly. Similar to file uploads, directly downloading files from S3 is so common that the AWS SDK has a shortcut operation for it. You can use
s3.getSignedUrl to sign generic S3 requests. You need to give it the related object key and the expiry time for the grant and specify the type of the S3 REST API operation. For retrieving objects, the REST API operation is called
getObject. The signature method returns a URL with query string parameters prepared according to the authorised grant.
A new file is created in the Lambda code directory, called
confirm-upload.js, using the following listing: