通过NodeJS服务器从Amazon S3传递文件而不公开S3 URL? [英] Pass files from Amazon S3 through NodeJS server without exposing S3 URL?

查看:462
本文介绍了通过NodeJS服务器从Amazon S3传递文件而不公开S3 URL?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试将S3文件存储集成到我的NodeJS应用程序中. 本教程解释了如何直接将 上载到S3.很好,但是它不适合我的需求,因为我希望只能通过Web应用程序的API来访问文件.我不希望这些文件在其S3 URL上公开可用,我只希望它们通过例如/api/files/<user_id>/<item_id>/<filename>可用.

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 needs, as I want the files to only be accessible via my web app's API. I don't want the files to be publicly available at their S3 URLs, I just want them to be available through for example /api/files/<user_id>/<item_id>/<filename>.

我希望下载通过我的API的原因是,以便我可以检查是否允许用户查看此特定文件.

The reason I want downloads to go through my API is so that I can check that the user is permitted to view this particular file.

我希望上载通过我的服务器的原因是,以便我知道要为文件名分配哪个<item_id>,因为这将与它的MongoDB _id属性相同.如果我先将该文件上传到S3,则在该项目首先具有Mongo _id时,我将无法执行此操作.

The reason I want uploads to go through my server is so that I know which <item_id> to assign the filename, as this will be the same as its MongoDB _id property. I can't do this if I upload the file to S3 before the item has a Mongo _id in the first place.

我看过但找不到简单的教程,该教程介绍如何通过我的NodeJS应用程序将文件从S3流传输到客户端,反之亦然.

I've looked but couldn't find a straightforward tutorial for how to stream files from S3 to the client and vice versa through my NodeJS application.

谢谢

推荐答案

快速中间件(用于检查发出请求的用户的授权)和

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.

以下是使用 multer 上传的完整示例.

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.

这篇关于通过NodeJS服务器从Amazon S3传递文件而不公开S3 URL?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆