use*_*833 9 authorization ruby-on-rails pundit
我正在写关于https://github.com/elabs/pundit#scopes
我的印象是授权应该回答问题您是否允许访问此资源?,即true
/ false
答案.所有行动都属于这种情况,除了index
Pundit的文档,ActiveRecord::Relation
根据谁的要求,应该返回不同的行为.例如,管理员获取scope.all
,而普通用户获取scope.where(:published => true)
.
应用程序/政策/ post_policy.rb
class Scope < Struct.new(:user, :scope)
def resolve
if user.admin?
scope.all
else
scope.where(:published => true)
end
end
end
Run Code Online (Sandbox Code Playgroud)
应用程序/控制器/ posts_controller.rb
def index
@posts = policy_scope(Post)
end
Run Code Online (Sandbox Code Playgroud)
我的保留意见是这是一个很滑的斜坡,很快我就会在范围内添加演示文稿(例如scope.all.order('created_at ASC')
) - 在授权政策中这样做很奇怪.
当然我可以把它移到控制器......
def index
@post = policy_scope(post)
if user.admin?
@post = @post.order( 'created_at ASC' )
end
end
Run Code Online (Sandbox Code Playgroud)
......但这是控制器的工作吗?而且我认为将这样的调用添加到视图中是不对的.那么也许它应该是一种模型方法?
你会说什么是做以下事情的利弊?
应用程序/控制器/ posts_controller.rb
这index
与其他方法一样,一次调用authorize
,一次调用模型方法.
def index
authorize(Post)
@posts = Post.index(current_user)
end
Run Code Online (Sandbox Code Playgroud)
应用程序/政策/ post_policy.rb
这只是给出了一个真/假的答案.你被授权了吗?是还是不是.
def index?
user.admin? || user.regular_user?
end
Run Code Online (Sandbox Code Playgroud)
应用程序/模型/ post.rb
在模型中我们可以像我们喜欢的那样花哨.
def self.index(user)
if user.admin?
Post.all.order('created_at ASC')
else
Post.where(user_id: user.id)
end
end
Run Code Online (Sandbox Code Playgroud)
思考?
Rob*_*Rob 11
我对Pundit授权与范围的理解如下:
authorization
:'是否允许此用户对此资源采取行动(创建/更新/销毁)?
within scope
:'该用户是否应该能够看到(索引/显示)此资源?'
授权(authorize @resource
)推迟到permitted_attributes
在ResourcePolicy
寻找答案.
范围(policy_scope(Resource)
)遵循resolve
.
我相信Pundit范围背后的原因是代码中应该只有一个位置,您可以定义谁应该可以访问哪些资源.
正如您所描述的,您可以在控制器或视图中实现相同的行为.但是,如果您在某个控制器方法中忘记了适当的范围,那么将代码放入策略中以防止未经授权的访问.
我认为是policy_scope()
限制可见性的方法,而其他结果改进(例如排序)可以在控制器级别进行.然而,毫无疑问,在游戏中有很多个人偏好.
归档时间: |
|
查看次数: |
1572 次 |
最近记录: |