Devise + Rails 3.0.4 завершает сессию после AJAX-запроса - PullRequest
7 голосов
/ 26 февраля 2011

У меня есть действие, инициированное запросом AJAX, сгенерированным Ajax.InPlaceEditor или InPlaceCollectionEditor, например:

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

После достижения любого из методов рендеринга сеанс истекает, и в следующий раз, когда пользователь отправляет запрос, Devise отправляет их для входа в систему на странице.

Даже если я освобождаю поле update_field от аутентификации (before_filter :authenticate_user!, :except => :update_field) сеанс все еще сбрасывается.

Я посмотрел на ответ на очень похожий вопрос на Разработать сеанс, срок действия которого истекает при вызове .js [AJAX] , но это не решает мою конкретную проблему.

Есть идеи?

1 Ответ

11 голосов
/ 26 февраля 2011

Я получил это для работы, получив код из 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;
  }
}
});

... внутри блока Javascript в моем application.html.erb:

<script type="text/javascript">
  (... the code from above)
</script>

Также не забудьте добавить:

<%= csrf_meta_tag %>

в том же файле к началу (если его там еще нет).

Документ " Обход защиты CSRF в Ruby on Rails"объясняет, почему это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...