在快速/ nodejs应用程序中提供S3中存储的文件 [英] Serving files stored in S3 in express/nodejs app

查看:153
本文介绍了在快速/ nodejs应用程序中提供S3中存储的文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有应用程式,用户的照片是私人的。我在AWS s3中存储照片(缩略图)。网站上有一个页面,用户可以在其中查看他的照片(即缩略图)。现在我的问题是如何提供这些文件。我评估的一些选项是:




  • 使用签名网址生成从CloudFront(或AWS)提供文件。但问题是每次用户刷新页面时,我必须再次创建这么多签名的网址并加载它。所以我无法缓存浏览器中的图像,这将是一个不错的选择。有没有办法仍然在javascript?由于安全问题,我无法使这些网址更长时间的有效性。其次,在这个时间框架内,如果有人抓住该网址,他可以查看该文件,而不通过应用程序的身份验证。

  • 其他选项是从我的快速应用程序本身提供文件从S3服务器流式传输。这样我就可以拥有http缓存头,从而启用浏览器缓存。它还确保没有人可以在不经过身份验证的情况下查看文件。理想情况下,我想流式传输文件,而我正在使用NGINX代理中继另一方流向NGINX。但是,正如我所看到的,只有当文件存在于同一系统的文件中时才可能。但是在这里我必须流式传输并返回,当我得到流完成。不想在本地存储文件。



我无法评估这两个选项中哪一个会是更好的选择? ?我想将尽可能多的工作重定向到S3或云端,但是即使使用唱网址也会将请求首先发送到我的服务器。我也想要缓存功能。



那么什么是理想的方式呢?有关这些方法的具体问题的答案?

解决方案

我只是从S3流式传输。这很容易,而且签名的网址要困难得多。当您将图像上传到S3时,请确保您设置内容类型内容长度标题。

  var aws = require('knox')。createClient({
key:'',
秘密:'',
桶:''
})

app.get('/ image /:id',function(req,res,next){
if(!req.user.is.authenticated){
var err = new Error()
err.status = 403
next(err)
return $ b $

aws.get('/ image /'+ req.params.id)
.on('error',next)
.on('response' function(resp){
if(resp.statusCode!== 200){
var err = new Error()
err.status = 404
next(err)
return
}

res.setHeader('Content-Length',resp.headers ['content-length'])
res.setHeader('Content-Type' ,resp.headers ['content-type'])

//缓存控制?
// etag?
//最后修改?
//过期?

if(req.fresh){
res.statusCode = 304
res.end()
return
}

if(req.method ==='HEAD'){
res.statusCode = 200
res.end()
return


resp.pipe(res)
})
})


I have app where user's photos are private. I store the photos(thumbnails also) in AWS s3. There is a page in the site where user can view his photos(i.e thumbnails). Now my problem is how do I serve these files. Some options that I have evaluated are:

  • Serving files from CloudFront(or AWS) using signed url generation. But the problem is every time the user refreshes the page I have to create so many signed urls again and load it. So therefore I wont be able to cache the Images in the browser which would have been a good choice. Is there anyway to do still in javascript? I cant have the validity of those urls for longer due to security issues. And secondly within that time frame if someone got hold of that url he can view the file without running through authentication from the app.
  • Other option is to serve the file from my express app itself after streaming it from S3 servers. This allows me to have http cache headers, therefore enable browser caching. It also makes sure no one can view a file without being authenticated. Ideally I would like to stream the file and a I am hosting using NGINX proxy relay the other side streaming to NGINX. But as i see that can only be possible if the file exist in the same system's files. But here I have to stream it and return when i get the stream is complete. Don't want to store the files locally.

I am not able to evaluate which of the two options would be a better choice?? I want to redirect as much work as possible to S3 or cloudfront but even using singed urls also makes the request first to my servers. I also want caching features.

So what would be ideal way to do? with the answers for the particular questions pertaining to those methods?

解决方案

i would just stream it from S3. it's very easy, and signed URLs are much more difficult. just make sure you set the content-type and content-length headers when you upload the images to S3.

var aws = require('knox').createClient({
  key: '',
  secret: '',
  bucket: ''
})

app.get('/image/:id', function (req, res, next) {
  if (!req.user.is.authenticated) {
    var err = new Error()
    err.status = 403
    next(err)
    return
  }

  aws.get('/image/' + req.params.id)
  .on('error', next)
  .on('response', function (resp) {
    if (resp.statusCode !== 200) {
      var err = new Error()
      err.status = 404
      next(err)
      return
    }

    res.setHeader('Content-Length', resp.headers['content-length'])
    res.setHeader('Content-Type', resp.headers['content-type'])

    // cache-control?
    // etag?
    // last-modified?
    // expires?

    if (req.fresh) {
      res.statusCode = 304
      res.end()
      return
    }

    if (req.method === 'HEAD') {
      res.statusCode = 200
      res.end()
      return
    }

    resp.pipe(res)
  })
})

这篇关于在快速/ nodejs应用程序中提供S3中存储的文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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