paperclip の保存ディレクトリ名あるいはファイル名をid連番ではなく、MD5とかSHA1のハッシュ値にするメモ
画像を扱う際のrailsプラグインpaperclip
GitHub - thoughtbot/paperclip: Easy file attachment management for ActiveRecord
基本的な使い方は、githubとか紹介ページを参照してもらうとして、
ここでは画像保存のディレクトリ名あるいはファイル名をid連番ではなく、
推測しにくい値にする方法をメモしておきます
前置き
まず、デフォルトの設定だと保存pathは、
:rails_root/public/system/:attachment/:id/:style/:filename
らしいです。
なので、例えばimageモデルで、
has_attached_file :image, :styles => { :thumb => "100x100#", :mini => "30x30#" }
のようにしていたとすると、
hoge.jpgをアップロードして保存した際には、各画像は下記のpathで保存されます
public/system/images/1/original/hoge.jpg
public/system/images/1/thumb/hoge.jpg
public/system/images/1/mini/hoge.jpg
上のようにデフォルトのまま使わないにしても、
画像ごとにユニークなpathを作るために、
ディレクトリ名かファイル名のどこかにidを入れる可能性は高いかなと思います
例えば、
has_attached_file :image, :styles => { :thumb => "100x100#", :mini => "30x30#" }, :path => ":rails_root/public/sys_img/:id/:style.:extension", :url => "#{ActionController::Base.relative_url_root}/sys_img/:id/:style.:extension"
public/sys_img/1/original.jpg
public/sys_img/1/thumb.jpg
public/sys_img/1/mini.jpg
ただこのような連番idでは、URLのid部分を変更して直アクセスすることで、
他の画像を見ることができるということを、ユーザに想像される可能性は高いです
別に、見られて問題ない画像しかなければ良いですが、
例えば、予め画像データだけはアップロードしてあるが、
まだ、サイトにはリンクや埋め込みをしておらず、
それをするまでは画像を見られたくない場合において、連番idは危険度が高いと思います
確実な解決方法としては、
「画像の公開日付みたいなカラムを持ち、
画像をユーザが直接アクセスできない場所に保存して、
コントローラ経由で画像を出力する」、ことだとは思いますが、
そこまでしなくても、「連番idをやめて、推測しにくいpathに画像を保存する」
ことができればそれで良い場合もあると思います
で、どうするかというと
で、前置きが長くなっちゃいましたが、どうするかというと、
config/initializers/ の下に適当なファイル名(例えば、paperclip.rb)でファイルを作って、その中に次のように記述します
Paperclip::Attachment.interpolations[:id_sha1] = proc do |attachment, style| Digest::SHA1.hexdigest(attachment.instance.id.to_s) end
で、モデルでは定義した :id_sha1 を使って、
has_attached_file :image, :styles => { :thumb => "100x100#", :mini => "30x30#" }, :path => ":rails_root/public/sys_img/:id_sha1/:style.:extension", :url => "#{ActionController::Base.relative_url_root}/sys_img/:id_sha1/:style.:extension"
とすることで、idのSHA1ハッシュ値をディレクトリ名にすることができます
public/sys_img/356a192b7913b04c54574d18c28d46e6395428ab/original.jpg
public/sys_img/356a192b7913b04c54574d18c28d46e6395428ab/thumb.jpg
public/sys_img/356a192b7913b04c54574d18c28d46e6395428ab/mini.jpg
もちろんURLも:urlに書いておけばちゃんと作ってくれます
# viewファイルにて image.image.url(:mini) # /sys_img/356a192b7913b04c54574d18c28d46e6395428ab/mini.jpg
画像の created_at とか secret_key を混ぜれば、ほぼ推測されることはないかと思います
config/initializers/paperclip.rb
Paperclip::Attachment.interpolations[:mix_sha1] = proc do |attachment, style| secret_key = "paperclip_test's secret key string" Digest::SHA1.hexdigest("#{attachment.instance.id}#{attachment.instance.created_at.to_i}#{secret_key}") end