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

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

[Hold on] I've made a tool to help people building presentations the modern way.
If you are curious, here the starting point. [/Hold on]

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.