Rails Rails 生产环境下,默认把资源文件预编译到 public/assets,这样安全吗?

wcc526 · 2014年06月17日 · 最后由 wcc526 回复于 2014年06月17日 · 3878 次阅读

public 目录是对外所有可见的,但是有些资源我不想被直接访问。Rails 生产环境下,默认把资源文件预编译到public/assets,这样安全吗?

共收到 15 条回复

这样做的 目的 是为了不走Rails 应用程序, 直接通过nginx 获取资源文件, 从而提高响应速度。 另外由于assets 中存放的是css, js, image等一些静态文件 所以不存在安全问题。

#1楼 @meeasyhappy 但是有些images我想只让特定用户可以访问。如果这样的话,放在public/assets会不会不太好?有没有好的解决办法?

@wcc526 这种场景好像不多见,能具体描述一下吗

#3楼 @billy @Rei 谢谢!我的场景是,网页上有一个1.jpg图片,用户A编辑后,图片经过修改变成了2.jpg,这个2.jpg需要在网站上显示出来且只能对这个用户A可见。感觉这个2.jpg我不能把它放在assets目录下,不然的话,在produciton环境下就对所有用户可见了。

@wcc526 public/assets/images 下面的 一些图片是为Rails 应用程序服务, 按照Rails的约定, 这下面的文件是所有人都 能访问的。

还有一些图片是用户上传的 常放到public/uploads/文件下。一般来说 在Rails view 层面 控制 是否显示 就够了。如果说 用户知道图片名字可以 在浏览器 直接敲入url 访问。

如果说 你非要控制 一些人 不管怎样 都不能访问, 比如说public/upload/vip 下面的一些文件 不能访问, 那么 可以通过配置nginx 将 请求url包括这个前缀的请求 转发到Rails 应用程序 处理, 然后在程序里面 控制 访问权限了。

#4楼 @Rei 谢谢!send_file是用于提供下载的,但是我的场景是图片修改后,要在网站上显示出来。那么这个修改后的图片我要放在哪个目录下?

#7楼 @wcc526 send_file 发送的文件也可以用于页面显示的,只要是 img src 指定地址。

存放文件更好的选择是用 S3 七牛这里储存服务,用 token 控制访问权限。

#9楼 @Rei 非常感谢!

看了你的场景,这些images肯定不能放在assets里面,因为它们本来就不是assets,而是用户上传的文件。应该放在uploads或类似文件夹下,就像@meeasyhappy 说的。

对于这个场景,我觉得可以这么处理:

  1. 网站本身的图片也不放在assets里面,而是另起目录。因为这些图片在这里严格来说已经不是assets了,而是数据,需要在数据库里面有记录。而且作为assets可能比较多,compile很费时间。
  2. 用户A修改1.jpg后,生成一个带token的文件名。这个文件可以外部访问,但基本不可能拿到url, 除非用户A主动分享。同时数据库存入这个文件名。user_a.images << complex_token.jpg
  3. 用户A在界面上可以看到他修改的文件。这个很简单,数据库取文件名即可。

#11楼 @billy 非常感谢!

不客气。要是这么做的话,别忘了robots.txt也要设置不允许访问图片,或者某个目录下的图片。

#13楼 @billy 我现在打算的作法是直接在Rails.root 下建一个files目录,存放这些私有文件。这样合理吗?由于是比较小的应用,另外这些文件有些是属于临时文件,不太想通过数据库来访问。直接在Rails.root下建目录,会不会很不rails?

@wcc526 就像你说的,确实不合理。应用是应用,数据是数据,两者不能混在一起。如果是assets图片,那么也是应用的一部分,可以在一起。如果是数据类型的图片,那就不太合适。

这个情况,如果是图简便的话,也可以这么做:

  1. Rails .gitignore里面先忽略数据文件夹,比如/data
  2. 建立root/data/images/, 放入你的图片。如果愿意可以在这里新建git
  3. 新建一个Capistrano任务,不跟随deploy启动,而是手动执行。任务内容是把root/data/images复制到服务器相应目录,比如public/uploads/images。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册