AVISO: Não é possível verificar rails de autenticidade do token CSRF

Estou enviando dados do view para o controller com AJAX e recebi este erro:

AVISO: Não é possível verificar a autenticidade do token CSRF

Eu acho que tenho que enviar este token com dados.

Alguém sabe como posso fazer isso?

Edit: Minha solução

Eu fiz isso colocando o seguinte código dentro da postagem do AJAX:

headers: { 'X-Transaction': 'POST Example', 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') }, 

Você deve fazer isso:

  1. Certifique-se de ter < %= csrf_meta_tag %> no seu layout

  2. Adicione beforeSend a toda a solicitação do ajax para configurar o header como abaixo:


 $.ajax({ url: 'YOUR URL HERE', type: 'POST', beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))}, data: 'someData=' + someData, success: function(response) { $('#someDiv').html(response); } }); 

Para enviar token em todas as solicitações que você pode usar:

 $.ajaxSetup({ headers: { 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content') } }); 

A melhor maneira de fazer isso é apenas usar < %= form_authenticity_token.to_s %> para imprimir o token diretamente no seu código de rails. Você não precisa usar o javascript para pesquisar o dom pelo token csrf como outras menções. basta adicionar a opção de headers como abaixo;

 $.ajax({ type: 'post', data: $(this).sortable('serialize'), headers: { 'X-CSRF-Token': '< %= form_authenticity_token.to_s %>' }, complete: function(request){}, url: "< %= sort_widget_images_path(@widget) %>" }) 

Se bem me lembro, você tem que adicionar o seguinte código ao seu formulário, para se livrar deste problema:

 < %= token_tag(nil) %> 

Não esqueça o parâmetro.

A atualização de um aplicativo antigo para o rails 3.1, incluindo a meta tag csrf, ainda não está resolvendo o problema. No blog rubyonrails.org, eles dão algumas dicas de atualização, e especificamente essa linha de jquery que deve ir na seção head do seu layout:

 $(document).ajaxSend(function(e, xhr, options) { var token = $("meta[name='csrf-token']").attr("content"); xhr.setRequestHeader("X-CSRF-Token", token); }); 

retirado desta postagem do blog: http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails .

No meu caso, a session estava sendo redefinida após cada solicitação de ajax. Adicionar o código acima resolveu esse problema.

Na verdade maneira mais simples. Não se preocupe em mudar os headers.

Assegure-se de ter:

 < %= csrf_meta_tag %> in your layouts/application.html.erb 

Basta fazer um campo de input oculto assim:

  

Ou se você quiser um post ajax jQuery:

 $.ajax({ type: 'POST', url: "< %= someregistration_path %>", data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "< %= form_authenticity_token %>" }, error: function( xhr ){ alert("ERROR ON SUBMIT"); }, success: function( data ){ //data response can contain what we want here... console.log("SUCCESS, data="+data); } }); 
  1. Certifique-se de ter < %= csrf_meta_tag %> no seu layout
  2. Adicione um beforeSend para include o token csrf na solicitação do ajax para definir o header. Isso é necessário apenas para solicitações de post .

O código para ler o csrf-token está disponível nos rails/jquery-ujs , portanto, é mais fácil usá-lo da seguinte maneira:

 $.ajax({ url: url, method: 'post', beforeSend: $.rails.CSRFProtection, data: { // ... } }) 

Eu só pensei em ligar isso aqui, pois o artigo tem a maior parte da resposta que você está procurando e também é muito interessante

http://www.kalzumeus.com/2011/11/17/i-saw-an-extremely-subtle-bug-today-and-i-just-have-to-tell-someone/

As respostas mais votadas aqui estão corretas, mas não funcionarão se você estiver executando solicitações entre domínios, porque a session não estará disponível, a menos que você diga explicitamente ao jQuery para passar o cookie da session. Veja como fazer isso:

 $.ajax({ url: url, type: 'POST', beforeSend: function(xhr) { xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')) }, xhrFields: { withCredentials: true } }); 

Você pode escrever globalmente como abaixo.

JS normal:

 $(function(){ $('#loader').hide() $(document).ajaxStart(function() { $('#loader').show(); }) $(document).ajaxError(function() { alert("Something went wrong...") $('#loader').hide(); }) $(document).ajaxStop(function() { $('#loader').hide(); }); $.ajaxSetup({ beforeSend: function(xhr) {xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content'))} }); }); 

Roteiro do Café:

  $('#loader').hide() $(document).ajaxStart -> $('#loader').show() $(document).ajaxError -> alert("Something went wrong...") $('#loader').hide() $(document).ajaxStop -> $('#loader').hide() $.ajaxSetup { beforeSend: (xhr) -> xhr.setRequestHeader('X-CSRF-Token', $('meta[name="csrf-token"]').attr('content')) } 

oops ..

Eu perdi a seguinte linha no meu application.js

 //= require jquery_ujs 

Eu substituí-lo e seu trabalho ..

======= ATUALIZADO =========

Após 5 anos, estou de volta com o mesmo erro, agora eu tenho o novo Rails 5.1.6 , e encontrei este post novamente. Assim como o círculo da vida.

Agora, qual foi o problema: o Rails 5.1 removeu o suporte para jquery e jquery_ujs por padrão, e adicionou

 //= require rails-ujs in application.js 

Ele faz o seguinte:

  1. forçar diálogos de confirmação para várias ações;
  2. fazer solicitações não-GET de hiperlinks;
  3. fazer formulários ou hiperlinks enviar dados de forma assíncrona com o Ajax;
  4. Os botões de envio tornam-se automaticamente desativados no envio do formulário para evitar que você clique duas vezes. (de: https://github.com/rails/rails-ujs/tree/master )

Mas por que não está incluindo o token csrf para o pedido ajax? Se alguém souber sobre isso em detalhes, apenas me comente. Eu aprecio isso.

De qualquer forma eu adicionei o seguinte no meu arquivo js personalizado para fazer o trabalho (Obrigado por outras respostas para me ajudar a alcançar este código):

 $( document ).ready(function() { $.ajaxSetup({ headers: { 'X-CSRF-Token': Rails.csrfToken() } }); ---- ---- }); 

Se você estiver usando javascript com jQuery para gerar o token em seu formulário, isso funciona:

  

Obviamente, você precisa ter o < %= csrf_meta_tag %> em seu layout Ruby.

Se você não estiver usando o jQuery e usando algo como API de busca para pedidos, você pode usar o seguinte para obter o csrf-token :

document.querySelector('meta[name="csrf-token"]').getAttribute('content')

 fetch('/users', { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', 'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]').getAttribute('content')}, credentials: 'same-origin', body: JSON.stringify( { id: 1, name: 'some user' } ) }) .then(function(data) { console.log('request succeeded with JSON response', data) }).catch(function(error) { console.log('request failed', error) }) 

Use jquery.csrf ( https://github.com/swordray/jquery.csrf ).

  • Rails 5.1 ou posterior

     $ yarn add jquery.csrf 
     //= require jquery.csrf 
  • Rails 5.0 ou antes

     source 'https://rails-assets.org' do gem 'rails-assets-jquery.csrf' end 
     //= require jquery.csrf 
  • Código fonte

     (function($) { $(document).ajaxSend(function(e, xhr, options) { var token = $('meta[name="csrf-token"]').attr('content'); if (token) xhr.setRequestHeader('X-CSRF-Token', token); }); })(jQuery); 

Para aqueles de vocês que precisam de uma resposta que não seja do jQuery, você pode simplesmente adicionar o seguinte:

 xmlhttp.setRequestHeader ('X-CSRF-Token', $ ('meta [nome = "csrf-token"]'). attr ('conteúdo'));

Um exemplo muito simples pode ser visto aqui:

 xmlhttp.open ("POST", "example.html", true);
 xmlhttp.setRequestHeader ('X-CSRF-Token', $ ('meta [nome = "csrf-token"]'). attr ('conteúdo'));
 xmlhttp.send ();

Se alguém precisar de ajuda relacionada com o Uploadify e o Rails 3.2 (como eu quando pesquisei este post no Google), este aplicativo de exemplo pode ser útil: https://github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3/blob/master /app/views/pictures/index.html.erb

verifique também a solução do controlador neste aplicativo

Estou usando o Rails 4.2.4 e não consegui descobrir por que estava recebendo:

 Can't verify CSRF token authenticity 

Eu tenho no layout:

 < %= csrf_meta_tags %> 

No controlador:

 protect_from_forgery with: :exception 

Chamando tcpdump -A -s 999 -i lo port 3000 estava mostrando o header sendo definido (apesar de não precisar configurar os headers com ajaxSetup – já foi feito):

 X-CSRF-Token: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX Content-Type: application/x-www-form-urlencoded; charset=UTF-8 X-Requested-With: XMLHttpRequest DNT: 1 Content-Length: 125 authenticity_token=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 

No final, estava falhando porque eu tinha cookies desativados. O CSRF não funciona sem que os cookies sejam ativados, portanto, essa é outra possível causa se você estiver vendo esse erro.

Eu lutei com essa questão por dias. Qualquer chamada GET estava funcionando corretamente, mas todas as PUTs gerariam um erro “Não é possível verificar a autenticidade do token CSRF”. Meu site estava funcionando bem até eu ter adicionado um certificado SSL ao nginx.

Eu finalmente tropecei nessa linha perdida em minhas configurações nginx:

 location @puma { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_set_header X-Forwarded-Proto https; # Needed to avoid 'WARNING: Can't verify CSRF token authenticity' proxy_pass http://puma; } 

Depois de adicionar a linha ausente “proxy_set_header X-Forwarded-Proto https;”, todos os meus erros de token CSRF são encerrados.

Espero que isso ajude alguém que também está batendo a cabeça contra a parede. haha