zoukankan      html  css  js  c++  java
  • rails 数据表单的保护:attr_accessor, attr_accessible and attr_protected

    attr_accessor是Ruby语言的内置方法,此方法是为变量自动生成get set方法,从而可以省去一堆重复的get set方法。

    attr_accessible和attr_protected是rails框架提供的方法,使用的场景是如下的情况:

    收到表单,传统的方式是这样的:

    user = User.new
    user.user_name = params["user[user_name]"]
    user.password = params["user[password]"]

    这个代码违法了DRY原则,所以rails支持用下面的方式来快速创建对象:

    user = User.new params[:user]

    通过CoC,此时会自动把params中的user_name和password赋值给user对象的对应属性。这样,不管user有多少个属性,只需要一行代码就搞定。

    user = User.new params[:user],这种赋值方式,rails这帮guy就骑了个名字叫做  mass assignment

    但是这个同时带来另外一个问题,User的某些属性不希望通过浏览器的方式(有可能是通过手动编写的程序提交表单,而不是通过浏览器的form)来修改,比如:user.is_admin,这样如果有人恶意通过程序来调用此接口,就会出现安全漏洞,把自己升级为管理员。

    为了避免这样的情况,rails提供了两个方法(attr_accessible和attr_protected),用来限制哪些属性可以通过这种方式更新,哪些属性不能这样。

    attr_accessible相当于是白名单,定义哪些属性可以被mass assignment(大量赋值)

    attr_protected相当于是黑名单,定义哪些属性不可以被mass assignment

    Mass assignemet是個Rails專屬,因為太方便而造成的安全性議題。ActiveRecord物件在新建或修改時,可以直接傳入一個Hash來設定屬性(這功能叫做Mass assignment):

    def create
      params[:user] #=> {:name => “ow3ned”, :is_admin => true}
      @user = User.create(params[:user])
    end
    
    def update
      @user = User.update_attributes(params[:user])
    end

    但是如果這個Model包含一些敏感屬性,例如此例中is_admin是個辨別是否是管理員的Boolean值,它不應該讓使用者可以修改。這時候我們就必須用attr_protectedattr_accessible方法來保護這些屬性:

    class User < ActiveRecord::Base
      attr_protected :is_admin
    end

    使用attr_protected是黑名單,在Mass assignment時就會略過這個is_admin這個屬性。或是使用attr_accessible則是白名單,在Mass assignment時只會設定這些屬性:

    class User < ActiveRecord::Base
      attr_accessible :name
    end    

    這些被保護的屬性如果要給值,你就必須手動來了,而且通常會在不同的Controller,例如只會出現在後台管理中:

    params[:user] #=> {:name => "ow3ned", :is_admin => true}
    @user = User.new(params[:user])
    @user.is_admin #=> false # not mass-assigned
    @user.is_admin = true
    @user.is_admin #=> true
     

     

  • 相关阅读:
    共享内存:mmap函数实现
    navigationItem.rightBarButtonItem 设置背景图片,颜色更改解决的方法
    C语言基础
    easyui datagrid合并相同数据的单元格。
    js 计算总页数的最高效方式
    取消本地文件夹与SVN服务器的关联
    扩展自easyui的combo组件的下拉多选控件
    利用art.template模仿VUE 一次渲染多个模版
    利用art.template模仿VUE
    JavaScript单独的模块中传递数据
  • 原文地址:https://www.cnblogs.com/rywx/p/2510597.html
Copyright © 2011-2022 走看看