English 中文(简体)
How to store private pictures and videos in Ruby on Rails
原标题:

Here s a story:

  • User A should be able to upload an image.
  • User A should be able to set a privacy. ("Public" or "Private").
  • User B should not be able to access "Private" images of User A.

I m planning to user Paperclip for dealing with uploads.

If I store the images under "RAILS_ROOT/public/images", anyone who could guess the name of the files might access the files. (e.g., accessing http://example.com/public/images/uploads/john/family.png )

I need to show the images using img tags, so I cannot place a file except public.

How can I ensure that images of a user or group is not accessible by others?

(If I cannot achieve this with Paperclip, what is a good solution?)

最佳回答

I would have Paperclip use S3 on the back-end, set uploaded files to private, and then use "Query String Request Authentication Alternative" to generate the URLs for my image tags.

http://docs.amazonwebservices.com/AmazonS3/2006-03-01/index.html?RESTAuthentication.html

问题回答

You may make your rails server output the contents of image files. This is done via a controller action (most of actions print HTML, but this one will print JPG, for example).

Then you may use your authorization system to restrict access on controller level!

class ImagesController
  #Default show Image method streams the file contents.
  #File doesn t have to be in public/ dir
  def show
    send_file @image.filename, :type => @image.content_type,
              :disposition =>  inline 
  end

  # Use your favorite authorization system to restrict access
  filter_access_to :show, :require => :view, :attribute_check => :true
end

In HTML code you may use:

<img src="/images/show/5" />

Here s how I did this in a similar application.

  • Store your images on Amazon S3 instead of the local file system. Paperclip supports this.
  • Set your :s3_permissions to "private" in your Paperclip options
  • In your Image model, define a method that let s you output an authorized, time-limited url for the image.

Mine looks like this:

def s3_url(style = :original, time_limit = 30.minutes)
  self.attachment.s3.interface.get_link(attachment.s3_bucket.to_s, attachment.path(style), time_limit)
end
  • You can then show images to people only if they re authorized to see them (implement that however you like)–and not have to worry about people guessing/viewing private images. It also keeps them from passing URLs around since they expire (the URL has a token in it).
  • Be warned that it takes time for your app to generate the authorized urls for each image. So, if you have several images on a page, it will affect load time.

If you want to host files yourself, you can perform authentication at the controller level as has been suggested. One of my applications has an AssetController that handles serving of files from the private directory, for example.

One thing I wanted to add is that you should review this guide for setting up X-Sendfile, which will let your application tell the web server to handle actually sending the files. You ll see much better performance with this approach.





相关问题
rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

SSL slowness in EC2

We ve deployed our rails app to EC2. In our setup, we have two proxies on small instances behind round-robin DNS. These run nginx load balancers for a dynamically growing and shrinking farm of web ...

Auth-code with A-Za-z0-9 to use in an URL parameter

As part of a web application I need an auth-code to pass as a URL parameter. I am currently using (in Rails) : Digest::SHA1.hexdigest((object_id + rand(255)).to_s) Which provides long strings like : ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

activerecord has_many :through find with one sql call

I have a these 3 models: class User < ActiveRecord::Base has_many :permissions, :dependent => :destroy has_many :roles, :through => :permissions end class Permission < ActiveRecord::...

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

How to get SQL queries for each user where env is production

I’m developing an application dedicated to generate statistical reports, I would like that user after saving their stat report they save sql queries too. To do that I wrote the following module: ...

热门标签