当尝试在 Rails 3 中渲染表单时,request_forgery_protection 中的 nil.[]
每当我尝试向页面添加 form_tag 时,Rails 都会在页面上抛出 NoMethodError,并给出以下错误输出和堆栈跟踪:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_controller/metal/request_forgery_protection.rb:114:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/abstract_controller/helpers.rb:55:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:582:in `token_tag'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:555:in `extra_tags_for_form'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:566:in `form_tag_html'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:573:in `form_tag_in_block'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:52:in `form_tag'
app/views/teams/new.html.erb:1:in `_app_views_teams_new_html_erb__114968057028112192_2181733580__2538292988913059192'
堆栈跟踪还有更多内容,但相关部分是它是从被调用的 form_tag 触发的,并且它会导致 request_forgery_protection。
当我从页面中删除 form_tag 时,错误仍然存在,但现在它是从 <%= csrf_meta_tag %>在我的应用程序布局中。
在这种情况下,跟踪还指向控制器中 request_forgery_protection 方法中的同一行,
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_controller/metal/request_forgery_protection.rb:114:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/abstract_controller/helpers.rb:55:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/csrf_helper.rb:9:in `csrf_meta_tag'
app/views/layouts/application.html.erb:5:in `_app_views_layouts_application_html_erb___1820392644171111615_2183801660__2538292988913059192'
我尝试在 ApplicationController 中注释掉“protect_from_forgery”,但这没有任何作用。我还尝试注释掉 csrf_meta_tag,当我注释掉 csrf_meta_tag 并结合删除 form_tag 时,将允许呈现操作。
为了调试这个,我试图使我的视图成为最基本的可能:
<div>
<h1>This is a Header</h1>
<%= form_tag do %>
Form contents
<% end %>
</div>
我的控制器如下:
class TeamsController < ApplicationController
before_filter :authenticate_user!
check_authorization
load_and_authorize_resource
def new
@team = Team.new
end
end
我尝试使用的相关宝石是:Devise、Cancan 和 Rails 3.0.5
编辑:我的会话转储如下如下——
_csrf_token: "iZRWhye/WBrzjWbKreJVIRpfTbfpbSaaJu3fMiW3wEg="
flash: {:notice=>"Signed in successfully."}
session_id: "85fc7d152a17ca884f5b299f4cde926b"
warden.user.user.key: ["User", [1], "$2a$10$KC66DL1T.71ERw4d4VHVq."]
warden.user.user.session: {"last_request_at"=>2011-08-02 22:03:57 UTC}
Rails throws a NoMethodError on a page whenever I try to add a form_tag to it, and gives the following error output and stack trace:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.[]
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_controller/metal/request_forgery_protection.rb:114:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/abstract_controller/helpers.rb:55:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:582:in `token_tag'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:555:in `extra_tags_for_form'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:566:in `form_tag_html'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:573:in `form_tag_in_block'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/form_tag_helper.rb:52:in `form_tag'
app/views/teams/new.html.erb:1:in `_app_views_teams_new_html_erb__114968057028112192_2181733580__2538292988913059192'
There's more to the stack trace, but the relevant portions are that it is being triggered from the form_tag being called and that it leads into a request_forgery_protection.
When I remove the form_tag from the page, the error persists but now it gets triggered from the
<%= csrf_meta_tag %> in my application layout.
The trace in this case also points to the same line in the request_forgery_protection method in the controller
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_controller/metal/request_forgery_protection.rb:114:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/abstract_controller/helpers.rb:55:in `form_authenticity_token'
ruby/1.9.1/gems/actionpack-3.0.5/lib/action_view/helpers/csrf_helper.rb:9:in `csrf_meta_tag'
app/views/layouts/application.html.erb:5:in `_app_views_layouts_application_html_erb___1820392644171111615_2183801660__2538292988913059192'
I've tried commenting out "protect_from_forgery" in my ApplicationController, but that does nothing. And I've also tried commenting out the csrf_meta_tag, which when I comment out in combination with removing the form_tag allows the action to render.
To debug this, I've tried to make my view the most basic possible:
<div>
<h1>This is a Header</h1>
<%= form_tag do %>
Form contents
<% end %>
</div>
And my controller is as follows:
class TeamsController < ApplicationController
before_filter :authenticate_user!
check_authorization
load_and_authorize_resource
def new
@team = Team.new
end
end
Relevant gems I'm trying to use are: Devise, Cancan, and Rails 3.0.5
Edit: My session dump is as follows -
_csrf_token: "iZRWhye/WBrzjWbKreJVIRpfTbfpbSaaJu3fMiW3wEg="
flash: {:notice=>"Signed in successfully."}
session_id: "85fc7d152a17ca884f5b299f4cde926b"
warden.user.user.key: ["User", [1], "$2a$10$KC66DL1T.71ERw4d4VHVq."]
warden.user.user.session: {"last_request_at"=>2011-08-02 22:03:57 UTC}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
将其放在您的视图中并粘贴输出:
如果您的控制器称为 HomeController,您将看到类似这样的内容:
某些内容可能会在委托链中的某个点重新定义会话方法。
Put this in your view and paste the output:
If your controller is called HomeController, you'll see something like this:
Something might be re-defining the session method at some point in the delegation chain.