IT story

경고 : CSRF 토큰 진위 여부를 확인할 수 없습니다

hot-time 2020. 4. 14. 19:15
반응형

경고 : CSRF 토큰 진위 여부를 확인할 수 없습니다


AJAX를 사용하여보기에서 컨트롤러로 데이터를 보내고 있는데이 오류가 발생했습니다.

경고 : CSRF 토큰 진위를 확인할 수 없습니다

나는이 토큰을 데이터와 함께 보내야한다고 생각합니다.

아무도 내가 어떻게 할 수 있는지 알고 있습니까?

편집 : 내 솔루션

AJAX 게시물에 다음 코드를 넣어서이 작업을 수행했습니다.

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

이 작업을 수행해야합니다.

  1. <%= csrf_meta_tag %>레이아웃에 있는지 확인하십시오

  2. 추가 beforeSend모든 아래와 같이 헤더를 설정하는 아약스 요청을 :


$.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);
  }
});

모든 요청에서 토큰을 보내려면 다음을 사용할 수 있습니다.

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

이를 수행하는 가장 좋은 방법은 실제로 <%= form_authenticity_token.to_s %>레일 코드에서 직접 토큰을 인쇄하는 데 사용 하는 것입니다. 다른 게시물에서 언급했듯이 자바 스크립트를 사용하여 csrf 토큰의 돔을 검색 할 필요는 없습니다. 아래와 같이 헤더 옵션을 추가하십시오.

$.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) %>"
})

올바르게 기억한다면이 문제를 해결하기 위해 양식에 다음 코드를 추가해야합니다.

<%= token_tag(nil) %>

매개 변수를 잊지 마십시오.


실제로 가장 간단한 방법입니다. 헤더 변경에 신경 쓰지 마십시오.

당신이 가지고 있는지 확인하십시오 :

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

다음과 같이 숨겨진 입력 필드를 수행하십시오.

<input name="authenticity_token" 
               type="hidden" 
               value="<%= form_authenticity_token %>"/>

또는 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);
    }
});

csrf 메타 태그를 포함하여 이전 앱에서 rails 3.1로 업그레이드해도 여전히 해결되지 않습니다. rubyonrails.org 블로그에서 업그레이드 팁, 특히 레이아웃의 헤드 섹션에있는 jquery 라인을 제공합니다.

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

이 블로그 게시물에서 가져 왔습니다 : http://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails .

필자의 경우 세션은 각 아약스 요청에 따라 재설정되었습니다. 위의 코드를 추가하면 문제가 해결되었습니다.


  1. <%= csrf_meta_tag %>레이아웃에 있는지 확인하십시오
  2. beforeSend헤더를 설정하기 위해 ajax 요청에 csrf-token을 포함 시키려면 a 추가하십시오 . 이것은 post요청 에만 필요 합니다.

csrf-token을 읽는 코드는에서 사용할 수 rails/jquery-ujs있으므로 다음과 같이 사용하는 것이 가장 쉽습니다.

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

기사에 당신이 찾고있는 대부분의 답변이 있으며 매우 흥미 롭기 때문에 여기에 링크한다고 생각했습니다.

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


여기에서 가장 많이 투표 된 답변은 정확하지만 도메인 간 요청을 수행하는 경우 jQuery에 세션 쿠키를 전달하도록 명시 적으로 지시하지 않으면 세션을 사용할 수 없으므로 작동하지 않습니다. 이를 수행하는 방법은 다음과 같습니다.

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

아래와 같이 전역으로 작성할 수 있습니다.

일반적인 JS :

$(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'))}
    });
});

커피 스크립트 :

  $('#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'))
  }

jQuery를 사용하지 않고 요청에 fetch API 와 같은 것을 사용하는 경우 다음을 사용하여 다음을 얻을 수 있습니다 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)
    })

jquery.csrf ( https://github.com/swordray/jquery.csrf )를 사용하십시오 .

  • 레일스 5.1 이상

    $ yarn add jquery.csrf
    
    //= require jquery.csrf
    
  • 레일스 5.0 이하

    source 'https://rails-assets.org' do
      gem 'rails-assets-jquery.csrf'
    end
    
    //= require jquery.csrf
    
  • 소스 코드

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


죄송합니다 ..

내 application.js에서 다음 줄을 놓쳤습니다.

//= require jquery_ujs

나는 그것을 교체하고 작동합니다 ..

======= 업데이트 됨 =========

5 년 후, 나는 같은 오류로 돌아 왔고 이제는 새로운 Rails 5.1.6을 가지고 있으며이 게시물을 다시 발견했습니다. 인생의 원처럼.

문제는 Rails 5.1 이 기본적으로 jqueryjquery_ujs대한 지원을 제거 하고 추가 한 것입니다.

//= require rails-ujs in application.js

다음과 같은 작업을 수행합니다.

  1. 다양한 행동에 대한 강제 확인 대화;
  2. 하이퍼 링크에서 비 GET 요청을합니다.
  3. 양식 또는 하이퍼 링크가 Ajax와 비동기식으로 데이터를 제출하게하십시오.
  4. 양식 제출시 제출 버튼이 자동으로 비활성화되어 두 번 클릭을 방지합니다. (보낸 사람 : https://github.com/rails/rails-ujs/tree/master )

그러나 왜 Ajax 요청에 csrf 토큰이 포함되어 있지 않습니까? 누군가 이것에 대해 자세히 알고 있다면 저에게 의견을 말하십시오. 알겠습니다.

어쨌든 나는 사용자 정의 js 파일에 다음을 추가하여 작동 시켰습니다 (이 코드에 도달하는 데 도움이되는 다른 답변 감사합니다)

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

jQuery와 함께 자바 스크립트를 사용하여 양식에 토큰을 생성하는 경우 다음과 같이 작동합니다.

<input name="authenticity_token" 
       type="hidden" 
       value="<%= $('meta[name=csrf-token]').attr('content') %>" />

분명히, 당신은 <%= csrf_meta_tag %>Ruby 레이아웃 에 있어야합니다 .


jQuery가 아닌 답변이 필요한 사람들은 다음을 간단하게 추가 할 수 있습니다.

xmlhttp.setRequestHeader ( 'X-CSRF-Token', $ ( 'meta [name = "csrf-token"]'). attr ( 'content'));

여기에서 매우 간단한 예를 볼 수 있습니다.

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

누군가가 Uploadify and Rails 3.2와 관련하여 도움이 필요한 경우 (이 게시물을봤을 때 나와 같이)이 샘플 앱이 도움이 될 수 있습니다. https://github.com/n0ne/Uploadify-Carrierwave-Rails-3.2.3/blob/master /app/views/pictures/index.html.erb

이 앱에서 컨트롤러 솔루션을 확인하십시오.


나는 며칠 동안이 문제로 어려움을 겪었습니다. 모든 GET 호출이 올바르게 작동했지만 모든 PUT에서 "CSRF 토큰 인증을 확인할 수 없습니다"오류가 발생합니다. nginx에 SSL 인증서를 추가 할 때까지 내 웹 사이트가 제대로 작동했습니다.

나는 마침내 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; 
}

누락 된 줄 "proxy_set_header X-Forwarded-Proto https;"를 추가하면 모든 CSRF 토큰 오류가 종료됩니다.

잘하면 이것은 벽에 머리를 때리는 다른 누군가를 도울 것입니다.


Rails 4.2.4를 사용하고 있는데 왜 내가 얻는 지 알 수 없었습니다.

Can't verify CSRF token authenticity

나는 레이아웃에있다 :

<%= csrf_meta_tags %>

컨트롤러에서 :

protect_from_forgery with: :exception

호출 tcpdump -A -s 999 -i lo port 3000은 헤더가 설정되어 있음을 보여주었습니다 (헤더를 설정할 필요는 없지만 ajaxSetup이미 완료되었습니다).

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

결국 쿠키가 꺼 졌기 때문에 실패했습니다. 쿠키를 사용하도록 설정하지 않으면 CSRF가 작동하지 않으므로이 오류가 표시 될 수 있습니다.

참고 URL : https://stackoverflow.com/questions/7203304/warning-cant-verify-csrf-token-authenticity-rails

반응형