Rails How can I set authenticity_token to false in all form?

aptx4869 · 2013年05月07日 · 最后由 fei0456116 回复于 2013年05月11日 · 3731 次阅读

需求是这样的:在保留protect_from_forgery,不设置action_controller.allow_forgery_protection = false的情况下(也就是依然开启 csrf protection)

怎样才能让 rails 的,或者 simple_form 的 form helper 在生成 form 的时候不产生隐藏的 csrf token 字段(这样就能直接对包含 form 的地方用 fragment-cache 了……)

skip_before_filter :verify_authenticity_token

#1 楼 @fresh_fish Well, obviously I DO want to keep verifing authenticity token, but just don't need them in the form

#2 楼 @aptx4869

单个 form 的话加个选项 authenticity_token: false, 所有 form 的话你要自己 hack form helper

另外记得用 javascript 把 token 补上

自己定义个全局的同名 helper 或者可以...

def form_for *xs, **opts, &p
  super *xs, {authenticity_token: false, **opts}, &p
end

#3 楼 @luikore 唔……和我现在干的做法差不多,不过我是对 simple_for_for 包装了一下:

def ng_form_for(record, options={}, &block)
  options[:authenticity_token] = false
  simple_form_for(record, options, &block)
end

然后因为是在用 angular.js,于是顺便给SimpleForm::Inputs::Base整了个 monkey patch

def initialize(builder, attribute_name, column, input_type, options = {})
    ... 
    ...
    parent_opj_name = builder.object_name.to_s.gsub('[', '.').gsub(']', '').gsub('_attributes', '')
    @input_html_options[:data] ||={}
    @input_html_options[:data].merge!({ 'ng-model' => "#{parent_opj_name}.#{attribute_name}"})
end

然后 form 中就自动生成 angularjs 所需的对应 ng-model,然后就再也不用手写前端数据绑定了…… 至于 authenticity_token 部分,angularjs 会自动处理,将 token 丢进 cookies 给它就行了,连 html head 中的 csrf-meta-tag 都能删掉了,然后整个页面就能直接 cache 了……

#4 楼 @luikore 弱问一下,你这里函数定义里面xs, **opts 的几个 * 是啥意思,我看 form_for 和 simple_form_for 的源码里面没用号啊:

def form_for(record, options = {}, &block)
def simple_form_for(record, options={}, &block)

#6 楼 @aptx4869 我没去查原本的签名, 就用任意长指定了...

  • *xs 任意多个参数, xs 为数组
  • **opts 任意多个选项, opts 为哈希

js remove 可行吗

需要 登录 后方可回复, 如果你还没有账号请 注册新账号