protect_from_forgery & ненавязчивый Javascript - PullRequest
13 голосов
/ 08 апреля 2009

У меня есть некоторый javascript, выполняющий ajax-вызов на моем сайте Rails:

$.ajax({type: "PUT", url: url, data: { dummy: data }, complete: function(data) {}});

Когда Rails получает его, он возвращает ActionController::InvalidAuthenticityToken Ошибка. Я хотел бы сохранить там материал protect_from_forgery, если это возможно ... Но я не знаю, как передать токен аутентификации из файла javascript?

Кто-нибудь может мне помочь?

Ответы [ 2 ]

21 голосов
/ 08 апреля 2009

Добавьте в свой макет перед запуском любой другой JS:

<script>
  function authToken() {
    return '<%= form_authenticity_token if protect_against_forgery? -%>';
  }
</script>

authToken закодировано как функция, поэтому менее вероятно, что вы случайно перезапишите его другим JavaScript.

В качестве альтернативы, в Rails 3 токен аутентификации встроен в тег <meta>, который можно прочитать с помощью:

<script>
  function authToken() {
    return $('meta[name="csrf-token"]').attr('content');
  }
</script>

В вашем основном JS вы можете затем вызвать authToken(), и он вернет ваш токен аутентификации в виде строки для включения в ваши вызовы Ajax. Например, используя jQuery:

$.ajax({
  type: 'PUT',
  url:  url,
  data: {
    foo: bar,
    authenticity_token: authToken()
  },
  complete: function(data) {}
});

Обратите внимание, что если вы используете встроенный в Rails помощник form_for, он автоматически добавляет маркер подлинности в скрытый ввод. Если вы хотите отправить все данные формы, включая скрытый токен авторизации, вы можете просто использовать:

var $form = $('form');
$.ajax({
  url:      $form.attr('action'),
  type:     $form.attr('method'),
              // "get" or "post"; overridden by Rails' hidden "_method"
              // input value, e.g., "put"
  data:     $form.serialize(),
              // Includes hidden "authenticity_token" and "_method" inputs
  complete: function(data) {}
});

Этот шаблон часто полезен, когда вы уже написали форму, которая работает без JS, и добавляете ненавязчивый слой JS, который просто отправляет данные формы через Ajax.

3 голосов
/ 30 мая 2009

Спасибо за вышеуказанное решение.
Я использую некоторые стандартные формы на своем сайте, которые не используют rails form_tag, поэтому я просто добавил его как скрытый элемент формы.

<form action="...">
    <%= hidden_field_tag 'authenticity_token', form_authenticity_token if protect_against_forgery? %>
    ... rest of form...
</form>

Работает угощение.

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