Pass files from Amazon S3 through NodeJS server without exposing S3 URL?

前端 未结 2 671
面向向阳花
面向向阳花 2021-02-09 02:55

I am trying to integrate S3 file storage into my NodeJS application. This tutorial explaining how to upload directly to S3 is very good, but it\'s not suitable for my n

2条回答
  •  情歌与酒
    2021-02-09 03:29

    A combination of an express middleware (to check the authorization of the user making the request) and the use of the Node AWS SDK should do the trick.

    Here is a full example using multer for the upload.

    var express = require('express');
    var app = express();
    var router = express.Router();
    var multer = require('multer');
    var upload = multer({
      dest: "tmp/"
    });
    var fs = require('fs');
    var async = require('async');
    var AWS = require('aws-sdk');
    // Configure AWS SDK here
    var s3 = new AWS.s3({
      params: {
        Bucket: 'xxx'
      }
    });
    
    /**
     * Authentication middleware
     *
     * It will be called for any routes starting with /files
     */
    app.use("/files", function (req, res, next) {
      var authorized = true; // use custom logic here
      if (!authorized) {
        return res.status(403).end("not authorized");
      }
      next();
    });
    
    // Route for the upload
    app.post("/files/upload", upload.single("form-field-name"), function (req, res) {
      var fileInfo = console.log(req.file);
      var fileStream = fs.readFileSync(fileInfo.path);
      var options = {
        Bucket: 'xxx',
        Key: 'yyy/'+fileName,
        Body: fileStream
      };
    
      s3.upload(options, function (err) {
        // Remove the temporary file
        fs.removeFileSync("tmp/"+fileInfo.path); // ideally use the async version
        if (err) {
          return res.status(500).end("Upload to s3 failed");
        }
        res.status(200).end("File uploaded");
      });
    });
    
    // Route for the download
    app.get("/files/download/:name", function (req, res) {
      var fileName = req.params.name;
      if (!fileName) {
        return res.status(400).end("missing file name");
      }
      var options = {
        Bucket: 'xxx',
        Key: 'yyy/'+fileName
      };
      res.attachment(fileName);
      s3.getObject(options).createReadStream().pipe(res);
    });
    
    app.listen(3000);
    

    Obviously this is only partially tested and lacks of proper error handling - but it hopefully it should give you a rough idea of how to implement it.

提交回复
热议问题