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

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

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

这样做的 目的 是为了不走 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 在界面上可以看到他修改的文件。这个很简单,数据库取文件名即可。

不客气。要是这么做的话,别忘了 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。
需要 登录 后方可回复, 如果你还没有账号请 注册新账号