我在我的rails 6应用程序中使用了。目前使用before_action: authenticate_user!的非用户禁用所有图像,这是很好的,但我希望允许record_type‘新闻’的图像在我的active_storage_attachments可以被用户和非用户查看。
下面的代码是我到目前为止所拥有的,查看ActiveStorage::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发布于 2020-08-23 11:43:56
您的代码的问题是您正在这样做:
(ActiveStorage::Attachment.where(record_type: 'News')).present?这将检查整个数据库,如果有任何attachment与record_type‘新闻’。但是,您需要检查用户试图访问的特定图像是否为“News”类型,然后允许他访问,或者不允许他访问。要做到这一点,一种方法是在您可以检查的表演动作上:
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因此,这将检查用户试图访问的特定对象。
添加:
可以使用一些授权库自动完成这种类型的授权,例如:
您也可以为来宾用户提供特定类型的图像,而其他类型的映像仅允许注册用户使用。
发布于 2020-08-27 03:04:50
这将与专家 gem一起使用( @Deep 这里中提到的选项之一)
# 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# 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发布于 2022-11-24 13:22:47
这里的其他答案对我的用例很有帮助,但是如果其他人很难找到原始记录来做模型特定的事情(就像我所做的那样),那么署名可能对获取其他检查、条件等所需的信息很有用。
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
endhttps://stackoverflow.com/questions/63543658
复制相似问题