在使用 Shrine 和 Rails 加密之前为图像文件设置 mime 类型
setting mime type for image files before they are encrypted with Shrine and Rails
我的应用程序加密并上传某些文件,然后让管理员可以看到它们。为了实现后一种功能,my encryption gem's documentation 建议使用如下所示的控制器操作:
def show
user = User.find(params[:id])
lockbox = Lockbox.new(key: Lockbox.attribute_key(table: "id_docs", attribute: "image"))
send_data lockbox.decrypt(user.id_docs.image.read), type: user.id_docs.image.mime_type, disposition: 'inline'
end
我想要流式传输文件,但浏览器不知道如何解释它,而是下载。文件在上传前已加密,Shrine 将这些文件的 mime 类型设置为 application/octet-stream
。
我的创建操作如下所示:
def create
image = params.require(:id_doc).fetch(:image)
respond_to do |format|
if Shrine.mime_type(image) == 'image/jpeg'
lockbox = Lockbox.new(key: Lockbox.attribute_key(table: "id_docs", attribute: "image"))
encrypted_image = lockbox.encrypt_io(image)
@id_doc = IdDoc.create(user_id: current_user.id, image: encrypted_image)
@id_doc.save
format.html { redirect_to root_path }
else
format.html { redirect_to current_path }
end
end
end
如果我不加密文件,mime类型保存为image/png
或image/jpeg
,这就是我想要的。
IdDoc.rb 有一个名为 :image
的虚拟属性,它映射到数据库中的一个 image_data
字段:
class IdDoc < ApplicationRecord
belongs_to :user
validates_presence_of :image
include IdDocUploader::Attachment(:image)
end
schema.rb
create_table "id_docs", force: :cascade do |t|
t.bigint "user_id"
t.text "image_data"
end
保存到image_data
的数据保存为json格式:{\"id\":\"iddoc/1/image/2de32e77f306f0e95aed24623e930683.png\",\"storage\":\"store\",\"metadata\":{\"filename\":\"Screen Shot 2020-10-31 at 7.24.08 AM.png\",\"size\":47364,\"mime_type\":\"application/octet-stream\"}}
如何在文件创建之前更改 mime_type
的值?有没有什么办法可以用 Shrine 做到这一点,或者我应该超级 hacky 并直接解析 json?
简单地说:我认为你并没有完全按照 Shrine 的意图来做这件事,有多种方法可以解决这个问题。我将对它们进行排名(在我看来,基于 complexity/appropriateness)最好到最差:
- 加密 could/should 被视为 Shrine processing/derivatives 概念的一部分。所以你想在那里执行处理并相应地设置元数据。 Shrine 作者本人在此处的线程中概述了处理原始文件的解决方案:https://discourse.shrinerb.com/t/keep-original-file-after-processing/50.
- 您可以手动覆盖元数据:https://shrinerb.com/docs/metadata#controlling-extraction。这可能意味着不使用基于属性的分配,而是直接调用附加器(见下文)。
- 您可以定义自己的 MIME 类型确定逻辑,如下所示:https://shrinerb.com/docs/plugins/determine_mime_type。
- 您已经在使用
Shrine.mime_type
。使用从中获得的值并将其存储在 id_docs
模型的单独数据库列 mime_type
中,然后在从数据库中读取时使用它。请注意,这可能隐含地意味着此列中的值与您从文件元数据的 MIME 类型中获得的值不同步。
直接使用附件:
mime_type = Shrine.mime_type(image)
# ...
@id_doc = IdDoc.create(user_id: current_user.id) do |id_doc|
id_doc.image_attacher.model_assign(encrypted_image, metadata: { mime_type: mime_type })
end
我的应用程序加密并上传某些文件,然后让管理员可以看到它们。为了实现后一种功能,my encryption gem's documentation 建议使用如下所示的控制器操作:
def show
user = User.find(params[:id])
lockbox = Lockbox.new(key: Lockbox.attribute_key(table: "id_docs", attribute: "image"))
send_data lockbox.decrypt(user.id_docs.image.read), type: user.id_docs.image.mime_type, disposition: 'inline'
end
我想要流式传输文件,但浏览器不知道如何解释它,而是下载。文件在上传前已加密,Shrine 将这些文件的 mime 类型设置为 application/octet-stream
。
我的创建操作如下所示:
def create
image = params.require(:id_doc).fetch(:image)
respond_to do |format|
if Shrine.mime_type(image) == 'image/jpeg'
lockbox = Lockbox.new(key: Lockbox.attribute_key(table: "id_docs", attribute: "image"))
encrypted_image = lockbox.encrypt_io(image)
@id_doc = IdDoc.create(user_id: current_user.id, image: encrypted_image)
@id_doc.save
format.html { redirect_to root_path }
else
format.html { redirect_to current_path }
end
end
end
如果我不加密文件,mime类型保存为image/png
或image/jpeg
,这就是我想要的。
IdDoc.rb 有一个名为 :image
的虚拟属性,它映射到数据库中的一个 image_data
字段:
class IdDoc < ApplicationRecord
belongs_to :user
validates_presence_of :image
include IdDocUploader::Attachment(:image)
end
schema.rb
create_table "id_docs", force: :cascade do |t|
t.bigint "user_id"
t.text "image_data"
end
保存到image_data
的数据保存为json格式:{\"id\":\"iddoc/1/image/2de32e77f306f0e95aed24623e930683.png\",\"storage\":\"store\",\"metadata\":{\"filename\":\"Screen Shot 2020-10-31 at 7.24.08 AM.png\",\"size\":47364,\"mime_type\":\"application/octet-stream\"}}
如何在文件创建之前更改 mime_type
的值?有没有什么办法可以用 Shrine 做到这一点,或者我应该超级 hacky 并直接解析 json?
简单地说:我认为你并没有完全按照 Shrine 的意图来做这件事,有多种方法可以解决这个问题。我将对它们进行排名(在我看来,基于 complexity/appropriateness)最好到最差:
- 加密 could/should 被视为 Shrine processing/derivatives 概念的一部分。所以你想在那里执行处理并相应地设置元数据。 Shrine 作者本人在此处的线程中概述了处理原始文件的解决方案:https://discourse.shrinerb.com/t/keep-original-file-after-processing/50.
- 您可以手动覆盖元数据:https://shrinerb.com/docs/metadata#controlling-extraction。这可能意味着不使用基于属性的分配,而是直接调用附加器(见下文)。
- 您可以定义自己的 MIME 类型确定逻辑,如下所示:https://shrinerb.com/docs/plugins/determine_mime_type。
- 您已经在使用
Shrine.mime_type
。使用从中获得的值并将其存储在id_docs
模型的单独数据库列mime_type
中,然后在从数据库中读取时使用它。请注意,这可能隐含地意味着此列中的值与您从文件元数据的 MIME 类型中获得的值不同步。
直接使用附件:
mime_type = Shrine.mime_type(image)
# ...
@id_doc = IdDoc.create(user_id: current_user.id) do |id_doc|
id_doc.image_attacher.model_assign(encrypted_image, metadata: { mime_type: mime_type })
end