Having trouble with signature verification for derivatives

I’m using a local hostname in development on port 3000
I uploaded the image file to s3 in a public folder and verified it exists.

I’m getting this error
“Provided signature does not match the calculated signature”
Which is the exact error in the derivation_endpoint.rb verify_url method

Do I have something misconfigured, or am I doing something else wrong?

#shrine.rb
Shrine.storages = {
local: Shrine::Storage::FileSystem.new(“public”, prefix: “uploads”),
cache: Shrine::Storage::S3.new(prefix: “cache”, **s3_options),
store: Shrine::Storage::S3.new(prefix: “upload”, **s3_options),
}

Shrine.plugin :activerecord # loads Active Record integration
Shrine.plugin :cached_attachment_data # enables retaining cached file across form redisplays
Shrine.plugin :restore_cached_data # extracts metadata for assigned cached files
Shrine.plugin :model, cache: false
Shrine.plugin :derivatives, storage: :local, upload: true
Shrine.plugin :derivation_endpoint, secret_key: “shrinesecretkey”

#routes.rb

mount ImageUploader.derivation_endpoint => “/images”

#image_uploader.rb

require “image_processing/mini_magick”
class ImageUploader < Shrine
plugin :derivation_endpoint,
secret_key: “shrinesecretkey”,
prefix: “images” # matches mount point

derivation :resized do |file, width, height|
ImageProcessing::MiniMagick
.source(file)
.resize_to_limit!(width.to_i, height.to_i)
end
end

#image.rb

include ImageUploader::Attachment(:image)

self.image.derivation_url(:resized, x, y)

Just to test things out I overrode the verify url method. But it looks like I’m a zero byte file for the image.

class Shrine
class UrlSigner
def verify_signature(string, signature)
#do nothing
end
end
end

After a lot of hunting I finally figured out the issue. I am in the process of upgrading from some old dragonfly code and I was still passing along nil for the y value so it would resize only based off the x value. There were never any errors so it took a while to hunt down the problem.

Hmm, I’m not sure exactly what caused the error here, but if you think there is a way to improve Shrine’s error reporting, I’m always open to that :slight_smile:

I’m not sure where the error occurred, if it was shrine, or ImageMagick. But using a nil value for x or y would still produce a url. And that url would return a 0 byte image. Since I was used to the way dragonfly and ImageMagick worked, passing a nil value was expected behavior. When nothing threw an error i spent hours thinking something was wrong with my configuration and working in that direction. I think a simple check for the values and raising an error would suffice.

Given that the error was in signature verification, which is a derivation_endpoint feature, the issue seems to be in Shrine. I wasn’t able to reproduce it, though:

require "shrine"
require "shrine/storage/memory"
require "image_processing/mini_magick"
require "down"

Shrine.storages = {
  cache: Shrine::Storage::Memory.new,
  store: Shrine::Storage::Memory.new,
}

class ImageUploader < Shrine
  plugin :derivation_endpoint, secret_key: "shrinesecretkey"

  derivation :resized do |file, width, height|
    ImageProcessing::MiniMagick
      .source(file)
      .resize_to_limit!(width.to_i, height.to_i)
  end
end

image = Down.download("https://s3-us-west-2.amazonaws.com/uw-s3-cdn/wp-content/uploads/sites/6/2017/11/04133712/waterfall-1140x760.jpg")
uploaded_file = ImageUploader.upload(image, :store)

[[400, nil], [nil, 400]].each do |args|
  derivation_path = uploaded_file.derivation_url(:resized, *args)

  # imitates a real HTTP request with a mock Rack env hash
  pp ImageUploader.derivation_endpoint.call(
    "REQUEST_METHOD" => "GET",
    "rack.input"     => StringIO.new,
    "PATH_INFO"      => derivation_path.split("?")[0],
    "QUERY_STRING"   => derivation_path.split("?")[1],
  )
end

The above returns successful responses in both cases.