通过 Node js Express 访问签名 URL 的 AWS S3

Accessing AWS S3 Signed URL via Node js Express

我正在尝试使用在 Node JS 和 Express 中创建的包装器 API 访问签署 URL 的 AWS S3。

我正在重定向 url 以使用 nginx 调用节点 API。在节点 API 中,我在从节点 API 返回响应之前根据 S3 URL 返回的文件类型设置 'Content-Type' 响应 headers。

当我访问 URL 以通过包装器节点 API 获取 S3 中的文档时,我没有获得任何内容。如果是 PDF 文件,我会看到空白屏幕。

下面是我用来在节点包装器 API 中从 S3 获取文档并中继相同响应的代码块。

const request = require('request');

request(s3SignedURL, function (error, result, body) {
    if (!error) {
        res.header('Content-Type','application/pdf');
        res.end(body);
    } else {
        res.status(500).send(error);
    }
});

[编辑]

我将上传 S3 文件的详细信息存储在 table 中,并在有人尝试访问文档时使用该 table 获取文档。下面是使用的完整代码。

const S3 = new AWS.S3();

app.get("/getFile/*", function (req, res) {
    var urlInfo = req.url;
    var urlInfoList = urlInfo.split("/");
    var accessCode = urlInfoList[2];
    var accessID = urlInfoList[3];

    if (!!accessID && !!accessCode) {
        db.getFileInfo(accessCode, accessID).then(function (fileInfo) {
            if (fileInfo.length > 0) {
                var S3Options = {
                    Bucket: Bucketname,
                    Key: fileInfo[0].fileS3Key,
                };
                S3.getObject(S3Options, function (err, data) {
                    res.attachment(fileInfo[0].fileS3Key);
                    res.send(data.Body);
                });

                // request(fileInfo[0].fileS3URL).pipe(res.set('Content-Type', 'application/pdf').set('Content-Disposition', 'inline'));
            } else {
                res.status(404).send("<html><head><title>404 Not Found</title></head><body bgcolor=\"white\"><center><h1>404 Not Found</h1></center><hr></body></html>");
            }
        }, function (fileErr) {
            console.log('fileErr');
            console.log(fileErr);
            res.status(404).send("<html><head><title>404 Not Found</title></head><body bgcolor=\"white\"><center><h1>404 Not Found</h1></center><hr></body></html>");
        });
    } else {
        res.status(404).send("<html><head><title>404 Not Found</title></head><body bgcolor=\"white\"><center><h1>404 Not Found</h1></center><hr></body></html>");
    }
});

这方面的任何帮助都会非常有用。

您得到一个空白屏幕,因为您还需要发送 Content-Disposition 参数。

顺便说一下,预签名 url 的目的是从公开暴露的环境(AWS 环境之外)获得对 s3 对象的临时访问权。您不必使用来自后端服务的预签名 URL 机制,您可以通过 SDK

安全地访问对象
const express = require('express');
const app = express();
const request = require('request');

app.get('/download-file', function (req, res) {

  // sdk way
  var s3 = new AWS.S3({});
  var options = {
    Bucket: 'my-bucket-name',
    Key: file,
  };
  s3.getObject(options, function (err, data) {
    res.setHeader('Content-disposition', `inline; filename="${filename}"`);
    res.end(data.Body, 'binary');
  });

  // http way
  request('https://s3-ap-southeast-2.amazonaws.com/my-bucket-name/mypdf.pdf')
    .pipe(res.set('Content-Type', 'application/pdf').set('Content-Disposition', 'inline; filename="mypdf.pdf"'))
})