我有一个由 Ajax.InPlaceEditor
或 InPlaceCollectionEditor
生成的 AJAX 请求触发的操作,如下所示:
new Ajax.InPlaceCollectionEditor('agent_email', 'inspections/<%= @inspection.id %>/update_field',
{
collection: [<% @agents.each do |agent| %>
'<%= agent.email %>',
<% end %>],
okText: 'Update',
cancelText: 'Never mind',
savingText: 'Updating...'
});
在另一端,该操作包含以下内容:
def update_field
--some code here--
if success
puts "stored change"
render :text => result
else
puts "did note change store"
render :text => inspection.errors.to_json, :status => 500
end
end
一旦到达任何渲染方法, session 就会过期,下次用户发送请求时,Devise 会将它们发送到登录页面。
即使我从身份验证中免除 update_field (before_filter :authenticate_user!, : except => :update_field
), session 仍然会被重置。
我在 Devise session immediately expiring on .js call [AJAX] 上查看了一个非常相似的问题的答案。 ,但这并不能解决我的特定问题。
有什么想法吗?
最佳答案
我通过从 http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails 获取代码来实现此功能。 (原型(prototype)-snippet.js):
/*
* Registers a callback which copies the csrf token into the
* X-CSRF-Token header with each ajax request. Necessary to
* work with rails applications which have fixed
* CVE-2011-0447
*/
Ajax.Responders.register({
onCreate: function(request) {
var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
if (csrf_meta_tag) {
var header = 'X-CSRF-Token',
token = csrf_meta_tag.readAttribute('content');
if (!request.options.requestHeaders) {
request.options.requestHeaders = {};
}
request.options.requestHeaders[header] = token;
}
}
});
...在我的 application.html.erb 的 Javascript block 内:
<script type="text/javascript">
(... the code from above)
</script>
另外不要忘记添加:
<%= csrf_meta_tag %>
在同一文件的顶部(如果还没有)。
文档“CSRF Protection Bypass in Ruby on Rails”解释了为什么它有效。
关于ajax - Devise + Rails 3.0.4 在 AJAX 请求后结束 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5124097/