Ruby on rails 这是允许后端Rails中的参数的安全方法吗?
在我的一个Rails(6.1.0)模型中,我有几个列需要根据用户角色保护它们不受CRUD操作的影响。我已经实现了前端表单输入禁用,但不确定是否正确/安全地保护后端。我尝试了几种方法,并在params对象上确定了这种条件连接,但由于这不是我在那里明确看到的,我不相信这是最佳做法和/或完全安全。有更好的方法吗 给定某些用户权限/访问级别:Ruby on rails 这是允许后端Rails中的参数的安全方法吗?,ruby-on-rails,Ruby On Rails,在我的一个Rails(6.1.0)模型中,我有几个列需要根据用户角色保护它们不受CRUD操作的影响。我已经实现了前端表单输入禁用,但不确定是否正确/安全地保护后端。我尝试了几种方法,并在params对象上确定了这种条件连接,但由于这不是我在那里明确看到的,我不相信这是最佳做法和/或完全安全。有更好的方法吗 给定某些用户权限/访问级别: class用户
class用户
我已经通过设置“readonly”属性处理了前端表单(为清晰起见,删除了Haml和类):
#标准格式字段
=表格标签:批准地区代码,“临时地区代码”
=form.text_字段:prov_dist_代码,值:@project.prov_dist_代码
#“受保护”表单字段
=form.label:dist_代码,“最终分发代码”,只读:!当前用户。是否具有管理员权限?
=form.text_字段:dist_代码,值:@project.dist_代码
=form.label:pcode,“pcode”
=form.text_字段:pcode,只读:!当前用户。具有管理员权限?,值:@project.pcode
然后在控制器中,我进一步保护列:
class ProjectsController ap您所做的实际上只是以编程方式创建一个参数数组,并使用splat操作符将该数组作为参数列表应用。这并不是天生的不安全。唯一真正的安全问题是您是否从用户处获取白名单的密钥
从代码审查的角度来看,它确实在控制器层中放置了大量的逻辑,很难对其进行测试,并为您的模型增加了更多的责任。因为您提到了Pundit,它实际上是整合授权逻辑的一个很好的选择,因为它很容易单独测试
class ApplicationPolicy < Pundit::Policy
# ...
private
def employee?
user.employee? || user.manager? || user.executive? || user.administrator? || user.superadmin? || user.developer?
end
def manager?
user.manager? || user.executive? || user.administrator? || user.superadmin? || user.developer?
end
def executive?
user.executive? || user.administrator? || user.superadmin? || user.developer?
end
def administrator?
user.administrator? || user.superadmin? || user.developer?
end
def superadmin?
user.superadmin? || user.developer?
end
def developer?
user.developer?
end
end
类应用程序策略
class ProjectPolicy attrs thanky you@max。这非常有用,为向权威人士过渡铺平了一条清晰的道路(在我的列表中)。我感谢你的努力和帮助,没问题。如果您的用户策略发展到无法控制的地步,您可以将其子类化,并创建一个管理策略和管理策略等。这就是Pundit的魅力——它只是OOP。
class ProjectPolicy < ApplicationPolicy
BASE_ATTRIBUTES = [
:network_id,
:dist_title,
:dist_description,
:prov_dist_code,
:name,
:hosts,
:guests
].freeze
# ...
def permitted_attributes
BASE_ATTRIBUTES.dup.then do |attrs|
attrs << :pcode if administrator?
attrs << :dist_code if manager?
end
end
end
class ProjectsController < ApplicationController
...
def create
@project = Project.new(permitted_attributes(@project))
if @project.save
redirect_to @project, notice: "Project was successfully created."
else
render :new
end
end
end