超自己満足プログラミング このページをアンテナに追加 RSSフィード

2010-08-31

[] paperclip の保存ディレクトリ名あるいはファイル名をid連番ではなく、MD5とかSHA1ハッシュ値にするメモ

画像を扱う際のrailsプラグインpaperclip

no title

基本的な使い方は、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では、URLid部分を変更して直アクセスすることで、

他の画像を見ることができるということを、ユーザ想像される可能性は高いです


別に、見られて問題ない画像しかなければ良いですが、

例えば、予め画像データだけはアップロードしてあるが、

まだ、サイトにはリンクや埋め込みをしておらず、

それをするまでは画像を見られたくない場合において、連番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"

とすることで、idSHA1ハッシュ値ディレクトリ名にすることができます

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

参考:旧日記

kawabeskawabes 2010/11/23 15:24 同じことをしたくてこれから調べようとしていた矢先でした。ありがたく参考にさせていただきます。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証