Upload on AWS S3 with Express.js and Vue.js - Part 1

1st December, 2019 - 4 min. read - in Tutorials - Go to Index

Hey, before scrolling, I've made a tool to help people building presentations the modern way.
If you don't mind, I'd like to ask some feedback about it. Here the starting point to learn more.
Much appreciated!

I’m refactoring my favorite side project.

Part of this relies on how the file-upload works both on the backend and frontend as well.

In PRESENTA the external files are uploaded using AWS S3 service. The real upload happens straight from the front-end app to the AWS servers. The backend is in charge only to request the one-time token from AWS. Here the flow:

The backend

In this tutorial, I’m explaining the backend code that is an Express.js based app. The dependencies (that need to be installed) are:

Here the minimal Express app:

const express = require('express')
const path = require('path')
const app = express()
const port = process.env.PORT || 3131

app.listen(port, () => console.log('Server is running on port: ' + port))

Set-up the CORS

We need a nice dialogue between the backend and the frontend, therefore, we enable the CORS communication with:

const cors = require('cors')
var origins = {
  origin: ['http://localhost:8080'],
  optionsSuccessStatus: 200,
  credentials: false
}
app.use(cors(origins))

Auth with AWS

Here the authentication with S3 using your personal credentials:

const aws = require('aws-sdk')
aws.config.region = 'eu-west-3'
const S3_BUCKET = process.env.S3_BUCKET_NAME

The route

In this little webserver contains only one route with comments between the lines

app.get('/s3', (req, res) => {
  
  // get the params from the initial request
  const fileName = req.query.filename
  const fileType = req.query.filetype
  const ext = path.extname(fileName)
	
  // define the location and the file name
  const pathName = path.join('myfoldertest', 'myuploadedfile' + ext)

  const s3 = new aws.S3()
	
  // configure the S3 object to get the token
  const s3Params = {
    Bucket: S3_BUCKET,
    Key: pathName,
    Expires: 60 * 15,
    ContentType: fileType,
    ACL: 'public-read'
  }
	
  // ask for the token
  s3.getSignedUrl('putObject', s3Params, (err, data) => {
    if (err) {
      return res.status(500).json(err)
    }

    const returnData = {
      signedRequest: data,
      url: `${pathName}`
    }
		
    // returning the token to the frontend
    res.status(200).json(returnData)
  })
})

This little server can be run with node index.js and it will listen at http://localhost:3131/s3 with the filename and the filetype parameters correctly set.

This is a bare-bone example without many error handling, just to demonstrate this particular functionality. Full source code here.

In part 2 I’ll dive in the frontend part, of course.

Stay tuned.


Spotted a typo or (likely) a grammar error? Send a pull request.