Ruby on rails 这是允许后端Rails中的参数的安全方法吗?

Ruby on rails 这是允许后端Rails中的参数的安全方法吗?,ruby-on-rails,Ruby On Rails,在我的一个Rails(6.1.0)模型中,我有几个列需要根据用户角色保护它们不受CRUD操作的影响。我已经实现了前端表单输入禁用,但不确定是否正确/安全地保护后端。我尝试了几种方法,并在params对象上确定了这种条件连接,但由于这不是我在那里明确看到的,我不相信这是最佳做法和/或完全安全。有更好的方法吗 给定某些用户权限/访问级别: class用户

在我的一个Rails(6.1.0)模型中,我有几个列需要根据用户角色保护它们不受CRUD操作的影响。我已经实现了前端表单输入禁用,但不确定是否正确/安全地保护后端。我尝试了几种方法,并在params对象上确定了这种条件连接,但由于这不是我在那里明确看到的,我不相信这是最佳做法和/或完全安全。有更好的方法吗

给定某些用户权限/访问级别:

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 ProjectsControllerap您所做的实际上只是以编程方式创建一个参数数组,并使用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 ProjectPolicyattrs 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