node.js - Pass files from Amazon S3 through NodeJS server without exposing S3 URL? -


i trying integrate s3 file storage nodejs application. this tutorial explaining how upload directly s3 good, it's not suitable needs, want files accessible via web app's api. don't want files publicly available @ s3 urls, want them available through example /api/files/<user_id>/<item_id>/<filename>.

the reason want downloads go through api can check user permitted view particular file.

the reason want uploads go through server know <item_id> assign filename, same mongodb _id property. can't if upload file s3 before item has mongo _id in first place.

i've looked couldn't find straightforward tutorial how stream files s3 client , vice versa through nodejs application.

thank you

a combination of express middleware (to check authorization of user making request) , use of node aws sdk should trick.

here full example using multer 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  *  * called routes starting /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 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 temporary file     fs.removefilesync("tmp/"+fileinfo.path); // ideally use async version     if (err) {       return res.status(500).end("upload s3 failed");     }     res.status(200).end("file uploaded");   }); });  // route 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 partially tested , lacks of proper error handling - should give rough idea of how implement it.


Comments

Popular posts from this blog

scala - 'wrong top statement declaration' when using slick in IntelliJ -

c# - DevExpress.Wpf.Grid.InfiniteGridSizeException was unhandled -

PySide and Qt Properties: Connecting signals from Python to QML -