Sunday, 2 April 2017

Allowing users to upload content to s3

I have an S3 bucket named BUCKET on region BUCKET_REGION. I'm trying to allow users of my web and mobile apps to upload image files to these bucket, provided that they meet certain restrictions based on Content-Type and Content-Length (namely, I want to only allow jpegs less than 3mbs to be uploaded). Once uploaded, the files should be publicly accessible.

Based on fairly extensive digging through AWS docs, I assume that the process should look something like this on my frontend apps:

const a = await axios.post('my-api.com/get_a3_id');

const b = await axios.put(`https://{BUCKET}.amazonaws.com/{a.id}`, {
   // ??
   headersForAuth: a.headersFromAuth,
   file: myFileFromSomewhere // i.e. HTML5 File() object
});

// now can do things like <img src={`https://{BUCKET}.amazonaws.com/{a.id}`} />
// UNLESS the file is over 3mb or not an image/jpeg, in which case I want it to be throwing errors

where on my backend API I'd be doing something like

import aws from 'aws-sdk';
import uuid from 'uuid';
app.post('/get_a3_id', (req, res, next) => {
  // do some validation of request (i.e. checking user Ids)
  const s3 = new aws.S3({region: BUCKET_REGION});
  const id = uuid.v4();
  // TODO do something with s3 to make it possible for anyone to upload pictures under 3mbs that have the s3 key === id
  res.json({id, additionalAWSHeaders});
});

What I'm not sure about is what exact S3 methods I should be looking at.


Here are some things that don't work:

  • I've seen a lot of mentions of (a very old) API accessible with s3.getSignedUrl('putObject', ...). However, this doesn't seem to support reliably setting a ContentLength -- at least anymore. (See http://stackoverflow.com/a/28699269/251162.)

  • I've also seen a closer-to-working example using an HTTP POST with form-data API that is also very old. I guess that this might get it done if there are no alternatives but I am concerned that it is no longer the "right" way to do things -- additionally, it seems to doing a lot of manual encrypting etc and not using the official node SDK. (See http://stackoverflow.com/a/28638155/251162.)



via Aaron Yodaiken

No comments:

Post a Comment