Posted at

paperclipのURI Obfuscationするときはmysqlのmillisecondsに気をつけよう

More than 3 years have passed since last update.

URIを曖昧化したいので、よくやります。


require


やろうとしていること

https://github.com/thoughtbot/paperclip#uri-obfuscation

avatar画像をユーザーごとに一意性を担保+セキュリティ担保のために曖昧化したい。


問題点

更新時にインスタンス上に持っていた値と、

なんでかDB上のavatar_file_updated_atとインスタンス上に持っていたavatar_file_updated_atが1秒ずれる

  def update_resource(resource, params)

unless params[:password].blank?
resource.update_with_password(params)
else
resource.update_without_password(params)
puts "###############################"
puts resource.avatar.updated_at.to_i
puts resource.reload.avatar.updated_at.to_i
puts "###############################"
binding.pry
resource
end
end

###############################
1427116216
1427116217 #-> あれぇぇぇ?
###############################


原因

で、そのハッシュを作るには主に、hash_secretとhash_dataを使います。

https://github.com/thoughtbot/paperclip/blob/e195ef66978636ac93cab949bf322568ed291f1c/lib/paperclip/attachment.rb#L317

    def hash_key(style_name = default_style)

raise ArgumentError, "Unable to generate hash without :hash_secret" unless @options[:hash_secret]
require 'openssl' unless defined?(OpenSSL)
data = interpolate(@options[:hash_data], style_name)
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.const_get(@options[:hash_digest]).new, @options[:hash_secret], data)
end

そのhash_dataはこんな感じです。

https://github.com/thoughtbot/paperclip/blob/e195ef66978636ac93cab949bf322568ed291f1c/lib/paperclip/attachment.rb#L19

        :hash_data             => ":class/:attachment/:id/:style/:updated_at",

で、これのupdated_atが含まれているからhash値が変わってしまう。


解決策

generate migrationにあるt.attachment :avatarはよく考えればmicrosecond対応していない。

こいつのせいで丸められてしまっている忘れてた。なので、mysql側をちゃんとmicrosecondに対応させるだけです。

  def up

change_column :suppliers, :avatar_updated_at, :datetime, limit: 6
end

postgreに早く変えたい。