2012-05-02 3 views
8

나는 내가 작성한 레일 응용 프로그램에 액세스하기 위해 나머지 클라이언트를 사용하여 놀고있었습니다. 로그인하고 게시물을 요청하는 빠른 스크립트를 작성했습니다. 모든 것이 작동하지만 json에서 양식을 요청하면 authenticity_token이 제공되지 않는다는 사실을 확인해야했습니다. 나는 authenticity_token을 얻고 다른 사람에게 정기적 인 html 요청을해야만했다. 그런 다음이 게시물을 내 게시물 요청의 일부로 제출 한 json에 포함시켰다. 기본적으로 나는이 JSON 요청에 대한 CSRF 보호를 해제 할 수있는 옵션입니다하지만 난 오히려 그렇게하지 않을json 게시 요청에 대한 csrf 토큰을 레일 응용 프로그램에 게시

private_resource = RestClient::Resource.new('https://mysite.com') 

params = {:user => {:email => 'u[email protected]', :password => 'please'}} 
#log in 
login_response = private_resource['users/sign_in'].post(params, :content_type => :json, :accept => :json) 
#get cookie 
cookie = login_response.cookies 
#get json 
json_response = private_resource['products/new'].get(:content_type => :json, :accept => :json, :cookies => cookie) 
#another request that returns html form with authenticity token 
response_with_token = private_resource['products/new'].get(:cookies => cookie) 
#extract token 
token = Nokogiri::XML(response_with_token).css('input[name=authenticity_token]').first.attr('value') 
#update cookie 
cookie = response_with_token.cookies 
#populate form and insert token 
form = JSON.parse(json_response) 
form['name'] = "my product" 
form['authenticity_token'] = token 
#submit the request 
private_resource['products'].post(form.to_json, {:cookies => cookie, :content_type => :json, :accept => :json}) 

아래와 같은 빠른 더러운 스크립트가 있습니다. 나는 기계화 경로 또는 비슷한 것을 갈 수 있고 나서 CSRF로 json 요청에 대해 걱정하지 않을 것이지만 나머지 클라이언트와 함께이 작업을 수행하고 싶다.

내가 궁금한 점이 있다면 json 요청에 대한 authenticity_token이 제공되지 않는 이유가 있습니다. 여기에있는 꽤 해킹 된 접근법보다 토큰 문제를 푸는 데 더 좋은 방법이 있는지 궁금합니다.

답변

8

애플리케이션에 아래 코드를 입력하십시오. 컨트롤러 :

def verified_request? 
    if request.content_type == "application/json" 
     true 
    else 
     super() 
    end 
end 

before_filter를 사용하여이 메서드를 호출합니다. http://blog.technopathllc.com/2011/09/rails-31-csrf-token-authenticity-for.html

을 그리고 레일에서이 문제를 확인 : 자세한 내용은

확인 https://github.com/rails/rails/issues/3041

+1

답장을 보내 주셔서 감사합니다. 나는 CSRF 수표를 그냥 끄는 것을 피하려고했지만 추측합니다. 레일스가 어떤 토큰도 포함하고 있지 않지만 토큰을 검사하는 json 형식을 제공한다는 것이 약간 이상하게 보입니다. json 컨텐트에 대한 검사를 끄기보다는 포함 된 토큰으로 json 양식을 제공하는 것이 의미가 있습니까? – Conor

+0

환영합니다. 그렇습니다. CSRF 토큰 문제를 우회하는 유일한 방법입니다. JSON 요청으로 토큰을 전달하려면 header : { 'X-CSRF-Token': '<% = form_authenticity_token.to_s %>' – swati

+0

check : http : // stackoverflow와 같은 헤더를 사용할 수 있습니다. co.kr/questions/7203304/warning-cant-verify-csrf-token-authenticity-rails http://stackoverflow.com/questions/8503447/rails-how-to-add-csrf-protection-to-forms-created-in - 자바 스크립트 – swati

0

당신의 app/views/products/new.json.jbuilder,이를 추가

json.authenticity_token form_authenticity_token 

이 값의 존재와 키 "authenticity_token"를 삽입합니다 토큰이므로 json_response에서 토큰을 얻을 수 있습니다. 아이디어는 this answer입니다.

관련 문제