文件扩展名的 Shrine 验证不允许 Facebook 图片

Posted

技术标签:

【中文标题】文件扩展名的 Shrine 验证不允许 Facebook 图片【英文标题】:Shrine validation of file extension does not allow Facebook image 【发布时间】:2021-09-02 12:02:00 【问题描述】:

我将 Srhine 用于我的项目中的图像,并使用 Omniauth gems 通过 Google 和 Facebook 进行日志记录。

我从 Omniauth 提供者获取数据的方法是标准的:

  def self.from_omniauth(auth)
    where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
      user.email = auth.info.email
      user.name = [auth.info.first_name, auth.info.last_name].join(" ")
      user.password = Devise.friendly_token[0, 20]
      user.avatar_remote_url = auth.info.image
    end
  end

它允许我通过 Google 和 Facebook 登录并获取用户数据、姓名和图像。我也有标准注册和更新 user.avatar 的可能性,所以我想验证图像,使其大小有限,扩展也有限。我在 Uploader 类中编写了以下验证:

  Attacher.validate do
    validate_max_size 2*1024*1024
    # validate_extension %w[jpg jpeg png webp]
  end

问题是扩展验证不允许通过 Facebook 注册新用户。在 FB 的情况下,auth.info.image 并没有真正返回指向 'https://blabla/image.jpg' 之类的图像的链接,而是创建一个链接,当您将其粘贴到浏览器中时,会直接将图像下载到硬盘驱动器。如何编写此验证以允许保存提供图像的 FB 方式?或者我如何才能在 Omniauth 方法中跳过此验证?

【问题讨论】:

【参考方案1】:

您可以在附加文件之前在Shrine::Attacher 上下文哈希中设置自定义标志:

def self.from_omniauth(auth)
  where(provider: auth.provider, uid: auth.uid).first_or_create do |user|
    user.email = auth.info.email
    user.name = [auth.info.first_name, auth.info.last_name].join(" ")
    user.password = Devise.friendly_token[0, 20]
    user.avatar_attacher.context[:omniauth] = true # <=== set the flag
    user.avatar_remote_url = auth.info.image
  end
end

然后在 validate 块中,您可以访问它并在存在标志时跳过扩展验证:

Attacher.validate do
  validate_max_size 2*1024*1024
  validate_extension %w[jpg jpeg png webp] unless context[:omniauth]
end

【讨论】:

以上是关于文件扩展名的 Shrine 验证不允许 Facebook 图片的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET 文件上传 - 验证

Rails 6 - Shrine - ImageProcessing - 获取原始上传文件

在使用 Shrine 和 Rails 加密之前为图像文件设置 mime 类型

Rails 和 Shrine 创建带有附件的模型记录

多个 Shrine 上传者的共享衍生品配置

“上帝的操作系统” Shrine!既不是 Windows,也不是 Linux