【问题标题】:Rails image upload securityRails 图片上传安全
【发布时间】:2015-04-27 06:31:24
【问题描述】:

目前,我采用 Carrierwave 为用户提供图像。

但是,我几乎没有找到图像安全的解决方案,即如何为上传的图像设置图像授权,只允许同一组中的某些用户查看?

在挖掘 Facebook 的实现之后,我观察到他们将这些参数 (oh,oe, __gda_) 注入到图像 url

?oh=924eb34394&oe=55E07&__gda__=1436393492fc8bf91e1aec5

carrierwavepaperclip 是否有类似的实现?

谢谢

【问题讨论】:

    标签: ruby-on-rails-4 paperclip carrierwave image-uploading dropzone.js


    【解决方案1】:

    我在这方面做了很多工作(仅使用回形针)。

    有一种解决方案还可以,但需要大量处理。

    如果您只想隐藏文件以免被循环播放,您可以散列回形针附件,请参阅: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-action + 对每张图片的授权。使用 x-sendfile 与 Apache 一起使用可以更快地交付图像。

    参考: http://apidock.com/rails/ActionController/Streaming/send_file

    【讨论】:

      【解决方案2】:

      我从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 配置网址。

      【讨论】:

        【解决方案3】:

        默认情况下,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
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2013-10-11
          • 1970-01-01
          • 2012-09-18
          • 2013-07-09
          • 1970-01-01
          • 1970-01-01
          • 2023-01-18
          • 2020-11-08
          相关资源
          最近更新 更多