首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rails 6,设计和活动存储

Rails 6,设计和活动存储
EN

Stack Overflow用户
提问于 2020-08-23 05:19:14
回答 3查看 533关注 0票数 1

我在我的rails 6应用程序中使用了。目前使用before_action: authenticate_user!的非用户禁用所有图像,这是很好的,但我希望允许record_type‘新闻’的图像在我的active_storage_attachments可以被用户和非用户查看。

下面的代码是我到目前为止所拥有的,查看ActiveStorage::record_type是新闻的附件。这段代码显示了用户和非用户的所有图像,这并不理想。

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-08-23 11:43:56

您的代码的问题是您正在这样做:

代码语言:javascript
复制
(ActiveStorage::Attachment.where(record_type: 'News')).present?

这将检查整个数据库,如果有任何attachmentrecord_type‘新闻’。但是,您需要检查用户试图访问的特定图像是否为“News”类型,然后允许他访问,或者不允许他访问。要做到这一点,一种方法是在您可以检查的表演动作上:

代码语言:javascript
复制
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. 专家

您也可以为来宾用户提供特定类型的图像,而其他类型的映像仅允许注册用户使用。

票数 3
EN

Stack Overflow用户

发布于 2020-08-27 03:04:50

这将与专家 gem一起使用( @Deep 这里中提到的选项之一)

代码语言:javascript
复制
# controller
class ImagesController < ApplicationController
  def index
    authorize :image, :index?
    @images = policy_scope(ActiveRecord::Attachment)
  end

  def show
    @image = policy_scope(ActiveRecord::Attachment).find(params[:id])
    authorize @image, policy_class: ImagePolicy
  end
end
代码语言:javascript
复制
# policy
class ImagePolicy < ApplicationPolicy
  def index?
    true # must be true so that every can see the list
  end

  def show?
    true # optional: add more logic here
  end

  class Scope
    def initialize(user, scope)
      @user  = user
      @scope = scope
    end

    def resolve
      if user
        scope
      else        
        scope.where(record_type: 'News') # we limit the records here
      end
    end
  end
end
票数 0
EN

Stack Overflow用户

发布于 2022-11-24 13:22:47

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

代码语言:javascript
复制
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
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63543658

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档