ruby-on-rails 导轨6、设备和活动存储

k5ifujac  于 2022-11-26  发布在  Ruby
关注(0)|答案(3)|浏览(177)

我在我的rails 6应用程序中使用Devise和Active Storage。目前使用before_action: authenticate_user!禁用了所有非用户的图像,这很好,除了我想允许用户和非用户查看我的active_storage_attachments中带有record_type“新闻”的图像。
下面的代码是我到目前为止所拥有的,查看ActiveStorage::Attachment,其中record_type是新闻。这段代码显示了所有用户和非用户的图像,这是不理想的。

class ActiveStorage::BaseController < ActionController::Base
  before_action :allow_certain_assets
  include ActiveStorage::SetCurrent

  protect_from_forgery with: :exception
  
  private
  
  def allow_certain_assets
    if (ActiveStorage::Attachment.where(record_type: 'News')).present?
    else
      authenticate_user!
    end
  end
  
end
lc8prwob

lc8prwob1#

代码的问题在于您正在执行以下操作:

(ActiveStorage::Attachment.where(record_type: 'News')).present?

这将检查整个数据库是否有record_type为“News”的attachment。但您需要检查用户试图访问的特定图像是否为“News”类型,然后允许他或不允许他。一种方法是在show操作上检查:

def show
  # this code might be incorrect and I am not sure how you would be getting 
  # the attachment object but this would explain a way you can authenticate it
  @attachment = ActiveStorage::Attachment.find params[:id]
  authenticate_user! unless @attachment.record_type == 'News'
end

因此,这将检查用户尝试访问的特定对象。

附加内容:

这种类型的授权可以使用一些授权库自动完成,例如:

  1. CanCanCan
  2. Pundit
    在这里您可以允许访客用户使用某些类型的图像,而其他类型的图像只允许注册用户使用。
a2mppw5e

a2mppw5e2#

这将与Pundit gem(@Deep here提到的选项之一)一起使用
第一个

oxosxuxt

oxosxuxt3#

这里的其他答案对我的用例很有帮助,但是如果其他人很难获得原始记录来做特定于模型的事情(就像我一样),那么find_signed可能对获得其他检查、条件等所需的信息很有用。

class ActiveStorage::BaseController < ActionController::Base
  include Rails.application.routes.url_helpers
  include ActiveStorage::SetCurrent
  before_action :check_attachment
  protect_from_forgery with: :exception
  
  private

  def check_attachment
    blob_id = ActiveStorage::Blob.find_signed(params[:signed_id])
    attachment = ActiveStorage::Attachment.find_by(blob_id: blob_id)
    record = attachment.record_type.constantize.find(attachment.record_id)
    if # Other model specific checks
      # Can also redirect somewhere else here if needed:
      # redirect_to root_path, alert: 'You do not have permission to access this.'
    end
  end
end

相关问题