2010-06-17 2 views
5

사이트의 모든 AJAX POST 요청이 authenticity_token없이 전달 될 수있는 레일 규정이 있습니까?내 jquery AJAX POST 요청은 Authenticity Token (Rails)을 보내지 않고 작동합니다.

컨트롤러 메소드를 호출하는 Jquery POST ajax 호출이 있지만 그 안에 인증 코드를 넣지는 않았지만 호출이 성공합니다.

나는 또한 내가 오버로드되지 않았 음을 확인하기 위해 내 코드를 검색 한/development.rb

내와 ApplicationController은 'request_forgery_protection'를 가지고와 내 환경에서 false로

config.action_controller.consider_all_requests_local 

을 변경했습니다 ajax 인증 토큰을 보내주십시오.

수표를 사용하지 않는 메커니즘이 있습니까? CSRF 보호 기능이 작동하는지 여부는 확실하지 않습니다.

레일 2.3.5를 사용하고 있습니다. 선명도

업데이트 :

function voteup(url, groupid){ 
     $.ajax({ 
     type: "POST", 
     url: "/groups/" + groupid + "/submissions/voteup", 
     data: "url=" + url, 
     dataType: 'text', 
     success: function(data){ 
      var counter = "vote_" + url; 
      $('#vote_' + url.cleanify()).text(" " + data + " "); 
     } 
     }); 
    }; 

나는 다음 위의 함수를 호출하는 'HREF가있는 링크가 :

<a href='javascript:voteup(param1,param2)'>...</a> 
+0

내가 비슷한 질문에 대답 기억을 여기에 그것을 발견 : http://stackoverflow.com/questions/2725118/rails-request-forgery-protection-settings/2725991 # 2725991 로컬 요청 때문일 것입니다. 다른 포트 또는 다른 도메인에서 실행중인 앱에서 작동하지 않아야합니다. 예 : localhost : 3000에서 앱을 실행중인 경우 localhost : 3001에서 ajax POST를 수행 할 수 없습니다. –

+0

안녕 Shripad, 나는 당신의 게시물을 보았지만 어떻게 된 일입니까? Rails 마법과 관련된 것이 있습니까? 온라인으로 볼 때, 여전히 form_authenticity_token을 전송하는 방법에 대해 글을 쓰는 사람을 볼 수 있습니다. 따라서 고정되어 있다면, 왜 그렇게 할 필요가 있습니까? –

+0

이것은 Rails 마법과는 아무런 관련이 없습니다. Ajax는 도메인 자체 내에서 호출되는 경우 인증 토큰없이 작동합니다. ajax가 도메인에서 작동하도록 설정하는 것이 아니라 다른 도메인에서의 공격을 막기 위해 인증 토큰이 필요합니다. 그것이 애플리케이션 컨트롤러에서'protect_from_forgery'를 갖는 주된 이유입니다. 다른 도메인에서 가장 좋은 예는 "Myspace sammy worm"입니다. 봐봐. 그러면 인증 토큰이 필요한 이유를 알 수 있습니다. –

답변

6

여기 가능성이 시나리오는 당신이 사용하고 있다는 것입니다 jQuery를 사용하여 일반 Rails 양식을 직렬화하고 직렬화 된 인증 토큰 숨김 필드를 포함합니다 (Rails가 모든 양식에 추가 함). 당신이 제출하고있는 양식 생성 된 소스에서

봐 ... 그것은 당신이 당신이 할 수있는 다른 일이 authenticity_token 필드에 있는지 확인하기 위해 로그를 확인하다

<input name="authenticity_token" type="hidden" value="somethinghere...." /> 

를 볼 가능성이 높습니다 요청 매개 변수.

+1

일부 코드 샘플을 사용하여 질문을 업데이트했습니다. 로그에 authenticity_token 매개 변수가 전송되지 않습니다. –

3

레이아웃보기에서이 추가 : app/views/layouts/(something).html.erb

<% if protect_against_forgery? %> 
<script type="text/javascript" charset="utf-8"> 
    //<![CDATA[ 
    window._auth_token_name = "#{request_forgery_protection_token}"; 
    window._auth_token = "#{form_authenticity_token}"; 
    //]]> 
</script> 
<% end %> 

그리고 당신의 application.js에 :

$.ajaxSetup({ 
    'beforeSend': function(xhr) {xhr.setRequestHeader("Accept", "text/javascript")} 
}); 

$(document).ready(function() { 
// All non-GET requests will add the authenticity token 
// If not already present in the data packet 
$("body").bind('ajaxSend', function(elm, xhr, s) { 
    if (s.type == "GET") return; 
    if (s.data && s.data.match(new RegExp("\\b" + window._auth_token_name + "="))) return; 
    if (s.data) { 
    s.data = s.data + "&"; 
    } else { 
    s.data = ""; 
    // if there was no data, $ didn't set the content-type 
    xhr.setRequestHeader("Content-Type", s.contentType); 
    } 
    s.data = s.data + encodeURIComponent(window._auth_token_name) + "=" + encodeURIComponent(window._auth_token); 
}); 

당신의 application_controller.rb에서이 추가 IE/사파리가 올바른 수락받을 수 있도록하기 위해 헤더 :

def correct_safari_and_ie_accept_headers 
    ajax_request_types = [ 'text/javascript', 'application/json', 'text/xml'] 
     request.accepts.sort!{ |x, y| ajax_request_types.include?(y.to_s) ? 1 : -1 } if request.xhr? 
end 

이렇게하면 수락 헤더의 기본값은 text/html 대신 text/javascript, application/json 또는 text/xml이됩니다.

이제 일반 AJAX 통화를 수행 할 수 있습니다. auth 토큰을 전달합니다. 또한 CDATA 스크립트 태그 다음에 application.js 만 포함 시키십시오. 두 개의 전역 변수 window._auth_token_namewindow._auth_token이 필요합니다.

희망이 도움이됩니다.건배 :)

+0

코드를 보내 주셔서 감사하지만 내 문제는이 시점에서 내 게시물이 인증 토큰 없이도 작동한다는 것입니다. –

관련 문제