Rails 3.2.11 및 RSpec을 사용한 원시 JSON 데이터 POST
응용 프로그램이 이 부정 이용에 취약하지 않음을 확인하기 위해 RSpec에서 이를 커버하는 컨트롤러 테스트를 작성하려고 합니다.그러기 위해서는 raw JSON을 투고할 수 있어야 하는데, 아직 그 방법을 찾지 못한 것 같습니다.몇 가지 조사를 하면서, 저는 적어도 이전에는 이러한 방법을 사용할 수식을 수행했다고 판단했습니다.RAW_POST_DATAheader, 그러나 이것은 더 이상 작동하지 않는 것 같습니다.
it "should not be exploitable by using an integer token value" do
request.env["CONTENT_TYPE"] = "application/json"
request.env["RAW_POST_DATA"] = { token: 0 }.to_json
post :reset_password
end
Params 해시를 보면 토큰은 전혀 설정되어 있지 않고, 단지 다음과 같이 되어 있습니다.{ "controller" => "user", "action" => "reset_password" }XML을 사용하려고 해도, 일반 포스트 데이터만 사용하려고 해도, 어느 경우라도 기간이 설정되어 있지 않은 것 같습니다.
최근의 Rails 취약성으로 인해 파라미터의 해시 방식이 변경된 것은 알고 있습니다만, 아직 Raw data를 RSpec을 통해 게시할 수 있는 방법이 있습니까?직접 사용해도 될까요?Rack::Test::Methods?
지금까지 제가 알 수 있는 한 컨트롤러 사양 내에서 Raw POST 데이터 송신은 불가능하게 되었습니다.단, 요청 사양에서는 매우 쉽게 실행할 수 있습니다.
describe "Example", :type => :request do
params = { token: 0 }
post "/user/reset_password", params.to_json, { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' }
#=> params contains { "controller" => "user", "action" => "reset_password", "token" => 0 }
end
Raw JSON을 컨트롤러 액션(레일 3+)으로 송신하는 방법은 다음과 같습니다.
예를 들어 다음과 같은 루트가 있다고 합시다.
post "/users/:username/posts" => "posts#create"
그리고 몸이 json이기를 기대한다고 가정해 보겠습니다.
JSON.parse(request.body.read)
테스트 결과는 다음과 같습니다.
it "should create a post from a json body" do
json_payload = '{"message": "My opinion is very important"}'
post :create, json_payload, {format: 'json', username: "larry" }
end
{format: 'json'}그것을 가능하게 하는 마법입니다.또한 TestCase #post http://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-process의 소스를 보면 액션 뒤에 첫 번째 인수(json_post)가 있고 문자열일 경우 raw post body로 설정되며 나머지 arg는 정상적으로 해석됩니다.
rspec은 Rails 테스트 아키텍처 위에 있는 DSL일 뿐이라는 점도 중요합니다.그post위의 메서드는 Action Controller입니다.: 일부 rspec 발명이 아닌 Test Case #post.
컨트롤러 테스트에서는 RAW_POST_DATA를 명시적으로 설정하고 있습니다.
before do
@request.env['RAW_POST_DATA'] = payload.to_json
post :my_action
end
레일 5의 예:
RSpec.describe "Sessions responds to JSON", :type => :request do
scenario 'with correct authentication' do
params = {id: 1, format: :json}
post "/users/sign_in", params: params.to_json, headers: { 'CONTENT_TYPE' => 'application/json', 'ACCEPT' => 'application/json' }
expect(response.header['Content-Type']).to include 'application/json'
end
end
다음으로 raw json 데이터를 전송하는 컨트롤러 테스트의 전체 작업 예를 나타냅니다.
describe UsersController, :type => :controller do
describe "#update" do
context 'when resource is found' do
before(:each) do
@user = FactoryGirl.create(:user)
end
it 'updates the resource with valid data' do
@request.headers['Content-Type'] = 'application/vnd.api+json'
old_email = @user.email
new_email = Faker::Internet.email
jsondata =
{
"data" => {
"type" => "users",
"id" => @user.id,
"attributes" => {
"email" => new_email
}
}
}
patch :update, jsondata.to_json, jsondata.merge({:id => old_id})
expect(response.status).to eq(200)
json_response = JSON.parse(response.body)
expect(json_response['data']['id']).to eq(@user.id)
expect(json_response['data']['attributes']['email']).to eq(new_email)
end
end
end
end
중요한 부분은 다음과 같습니다.
@request.headers['Content-Type'] = 'application/vnd.api+json'
그리고.
patch :update, jsondata.to_json, jsondata.merge({:id => old_id})
첫 번째는 콘텐츠유형이 요구에 맞게 올바르게 설정되어 있는지 확인합니다.이것은 매우 간단합니다.두 번째 부분은 몇 시간 동안 골칫거리였습니다.처음 접근 방식은 상당히 달랐습니다만, Rails의 버그가 있는 것이 판명되어 기능 테스트에서는 Raw Post 데이터를 송신할 수 없게 되었습니다(단, 통합 테스트에서는 송신할 수 있습니다).이 회피책은 보기 흉한 것이지만(레일 4.1.8 및 r-specails 3.0.0에서는 유효합니다).
레일 4의 경우:
params = { shop: { shop_id: new_subscrip.shop.id } }
post api_v1_shop_stats_path, params.to_json, { 'CONTENT_TYPE' => 'application/json',
'ACCEPT' => 'application/json' }
@ @daniel-vandersluis의 에 대한 약간의 .rails 3.0.6, 를 사용하여, 를 참조해 주세요.rspec 2.99 ★★★★★★★★★★★★★★★★★」rspec-rails 2.99:
describe "Example", :type => :request do
params = { token: 0 }
post "/user/reset_password", params.merge({format: 'json'}).to_json, { 'CONTENT_TYPE' => 'application/json', 'HTTP_ACCEPT' => 'application/json' }
end
HTTP_ACCEPT큰가 없습니다(header는 header로 할 수).HTTP_ACCEPT 그냥 '그냥'일 수도 있어요.ACCEPT하지만, 제 경우, 이 기능이 작동하려면 , 파라메스가 다음과 같이 되어 있을 필요가 있습니다..merge({format: 'json'}) ★★★★★★★★★★★★★★★★★」.to_json
또 다른 변형:
describe "Example", :type => :request do
params = { token: 0 }
post "/user/reset_password", params.merge({format: 'json'}).to_json, { 'CONTENT_TYPE' => Mime::JSON.to_s, 'HTTP_ACCEPT' => Mime::JSON }
end
it it를 한다.Mime::JSON ★★★★★★★★★★★★★★★★★」Mime::JSON.to_sapplication/json헤더값으로 지정합니다.
언급URL : https://stackoverflow.com/questions/14775998/posting-raw-json-data-with-rails-3-2-11-and-rspec
'programing' 카테고리의 다른 글
| application.yml에서 루트 로깅 수준을 설정합니다. (0) | 2023.03.25 |
|---|---|
| angularjs에서와 같이 버튼을 사용하여 페이지를 탐색하는 간단한 방법이 있습니까? (0) | 2023.03.25 |
| 각도에서의 객체 속성으로 필터링하는 방법JS (0) | 2023.03.25 |
| DIV 요소가 TinyMCE 내에서 삭제되지 않도록 보호 (0) | 2023.03.25 |
| 반응 요소에 대한 클릭 이벤트 시뮬레이션 (0) | 2023.03.25 |