目前,我采用Carrierwave为用户提供图像。
但是,我几乎找不到图像安全的解决方案,即如何为上传的图像设置图像授权,只允许同一组中的某个用户查看?
在挖掘Facebook的实现后,我观察到他们将这些参数(哦,oe,__ gda_)注入图像网址
?oh=924eb34394&oe=55E07&__gda__=1436393492fc8bf91e1aec5
carrierwave 或回形针是否有类似的实施?
由于
答案 0 :(得分:1)
我对此工作了很多(仅限Paperclip)。
有一个解决方案没问题,但需要大量处理。
如果您只想隐藏文件,您可以散列回形针附件,请参阅:https://github.com/thoughtbot/paperclip/wiki/Hashing
如果您想在每个图片加载时授权用户,您可以这样做:
将您的文件移出公共文件夹
has_attached_file :image,
styles: { large: '1500x1500>', small: '250x250>'},
path: ':rails_root/storage/gallery/image/:style/:filename'
使用Sendfile查看文件
def show
send_file(object.image.path(:small), filename: object.image_file_name, type: "image/png",disposition: 'inline',x_sendfile: true)
end
然而,我有点不愿意实现这一点,例如图片库,因为它需要GET
- 动作+授权每个图像。使用x-sendfile
与Apache协同工作可以更快地传送图像。
价: http://apidock.com/rails/ActionController/Streaming/send_file
答案 1 :(得分:0)
我从https://makandracards.com/makandra/734-deliver-paperclip-attachments-to-authorized-users-only找到了回形针的好方法 虽然有点过时,但本文详细介绍了保护附件访问所需的一切,以及如何保护文件本身。本文介绍了实现它的所有步骤,包括Capistrano部署!
请务必通过更改以下内容来使用更新的路线:
map.resources :notes, :member => { :attachment => :get }
为:
resources :notes, only: [] do
member do
get :attachment
end
end
我也更新了以下链接:
link_to 'Download attachment', [:attachment, @note]
为:
link_to 'Download Attachment', attachment_note_path( @note.id )
另请参阅Paperclip changing URL/Path以配置网址。
答案 2 :(得分:0)
默认情况下,Carrierwave会在/public
中存储上传内容,其中所有内容都只是作为静态内容提供。如果您需要控制对此上传的访问权限,我首先要配置不同的存储路径
class TestUploader < CarrierWave::Uploader::Base
def store_dir
Rails.root.join('uploads', relative_path).to_s
end
def serving_path # Use this method to get the serving path of the upload
File.join '/uploads', relative_path
end
private
def relative_path
File.join model.class.model_name.plural, model.id.to_s
end
end
由于CarrierWave依靠公共资产服务来提供上传服务,因此您必须实施自己的文件服务方法。这是如何使用Rails
执行此操作的愚蠢示例class Test < ApplicationRecord
mount_uploader :file, TestUploader
end
Rails.application.routes.draw do
get '/uploads/:model/:id', to: 'uploads#get'
end
class UploadsController < ApplicationController
def get
# ... autorization logic
model = params.fetch(:model).singularize.camelcase.safe_constantize
return head 400 unless model.present?
send_file model.find(params.fetch(:id)).file.path
end
end