Я бы предложил создать контроллер, ограничивающий доступ к загрузкам. Хитрость заключается в том, чтобы обслуживать файл через контроллер, а не напрямую из Apache. Я предполагаю, что вы используете RestfulAuthentication и Paperclip здесь:
Это модель (фотография с вложенным изображением)
class Photo < ActiveRecord::Base
belongs_to :user
has_attached_file :image, #:styles => {:thumbnail => "100x100#", :large => "800x600>"},
:path => ":rails_root/assets/:attachment/:id_partition/:style/:basename.:extension",
:url => "/assets/:userid/:attachment/:id/:style"
end
Обратите внимание на атрибут url, который в сочетании с маршрутом, приведенным ниже, заставит доступ к изображению через контроллер, а не напрямую из общедоступного каталога. Также обратите внимание на атрибут: path, который указывает личный каталог ресурсов вместо общедоступного по умолчанию.
map.assets 'assets/:userid/:attachment/:id/:style', :controller => 'assets', :action => 'get', :conditions => {:method => :get }
Теперь это простой контроллер, который требует, чтобы пользователь вошел в систему, проверяет идентификатор пользователя и отправляет соответствующий файл обратно пользователю.
class AssetsController < ApplicationController
before_filter :login_required
def get
if current_user.id == params[:userid].to_i
@photo = Photo.find params[:id]
send_file @photo.image.path(params[:style]), :type => @photo.image_content_type, :disposition => 'inline'
else
render :nothing => true
end
end
end
Вы также должны указать :x_sendfile => true
в send_file, чтобы повысить производительность, позволив Apache взять на себя нагрузку по фактической обработке файла, как только ваш контроллер подтвердит его.