7

This question has been asked by many of users and I have tried all solutions but none of them have worked for.for ex: This Question here curl json post request via terminal to a rails app but still the same result.

I am trying to POST data through terminal using CURL by running this command:

curl -i -H 'Authorization: Token token'="9asdadsasd87t8ddaghsd" -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '{"request":{"sender_mobile":"12331212","recipient_mobile":"121231231","location":"Bangalore"}}'  http://localhost:3000/api/v1/requests

and Getting reponse:

HTTP/1.1 422 Unprocessable Entity 
Content-Type: text/html; charset=utf-8
Content-Length: 15450
X-Request-Id: f1025e69-9ff3-4bd1-9bd5-0679fbcc50bc
X-Runtime: 0.062784
Server: WEBrick/1.3.1 (Ruby/2.1.1/2014-02-24)
Date: Thu, 08 Jan 2015 10:35:45 GMT
Connection: Keep-Alive

with so much lines of garbage but I guess this response is sufficient to understand what might be the cause.Here is the link to complete error http://pastebin.com/n342HeYL

I am able to do GET request successfully with command:

curl -i 'http://localhost:3000/api/v1/requests' -H 'Authorization: Token token'="952aa4598ec2cd87c8b69056616a00af"

Response:

HTTP/1.1 200 OK 
X-Frame-Options: SAMEORIGIN
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Content-Type: application/json; charset=utf-8
Etag: "b956523e0345d2bb466d39823195b600"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 91d21235-246f-4557-a67a-92dca02b9cc1
X-Runtime: 0.011781
Server: WEBrick/1.3.1 (Ruby/2.1.1/2014-02-24)
Date: Thu, 08 Jan 2015 10:51:55 GMT
Content-Length: 486
Connection: Keep-Alive

So, I dont know whats wrong in POST request.

Here is my request_controller.rb file

module Api
  module V1
    class RequestsController < ApplicationController
      # skip_before_action :verify_authenticity_token
      before_filter :restrict_access

      respond_to :json

      def index
        respond_with Request.all
      end

      def show
        respond_with Request.find(params[:id])
      end

      def create
        respond_with Request.create(params[:request])
      end

      def update
        respond_with Request.update(params[:id], params[:request])
      end

      def destroy
        respond_with Request.destroy(params[:id])
      end

      private

      def restrict_access
        authenticate_or_request_with_http_token do |token, options|
          ApiKey.exists?(access_token: token)
        end
      end
    end
  end
end
Community
  • 1
  • 1
Abhinay
  • 1,796
  • 4
  • 28
  • 52
  • Can you comment this line `protect_from_forgery` from your application controller and check if its working ? From your log this is what I sense is causing the problem as the request is `POST` which is usually a form submission for rails. Check and let me know – Pramod Solanky Jan 08 '15 at 11:07
  • @PamioSolanky its "HTTP/1.1 500 Internal Server Error" – Abhinay Jan 08 '15 at 11:11
  • Debug it and solve the error since it server side or post the trace back to see what the error is :) Also in your log you could see these lines `ActionController::InvalidAuthenticityToken` `actionpack (4.1.5) lib/action_controller/metal/request_forgery_protection.rb:176:in `handle_unverified_request'` which means, for rails whenever a form is submitted, rails checks for its authenticity usually from a token that was generated by rails. So if there's no token or the token was tampered then rails will consider this as an attack. Hence it won't process the request. So clear the error – Pramod Solanky Jan 08 '15 at 11:16
  • Sorry but I didn't understood what you are trying to suggest. As you can see with the same authentication token i am able to do GET request. – Abhinay Jan 08 '15 at 11:27

1 Answers1

2

With respect to the conversation above, let me write an answer.

If you see a form in rails, it will have a line as mentioned below

<input name="authenticity_token" type="hidden" value="+wFCV3kv0X/WI0qb54BgYlDzi+Tp+6HIGM61a4O6gg0=">

Now, if in ApplicationController you have this line protect_from_forgery then it would always expect authenticity_token and if its not available, it will throw the error thats mentioned in your logs hence I suggested to remove that line because you won't be passing an authenticity_token as a param from you api POST requests.

The reason why your get request is working just fine is because rails doesn't expect authenticity_token on a GET request.

Now, you said you removed protect_from_forgery but you got an internal server error, well that has to be handled by you as it has got nothing to do with GET or POST request but it is an error in your rails application. So solve that error and it should work just fine. Or also post the error log here so may be I can help you with that.

EDIT: Solution to your internal server 500 error

With the logs pasted below, it is also necessary that you allow the attributes in your controller, just as @abhinay mentioned in the code.

Hope that helps

Pramod Solanky
  • 1,690
  • 15
  • 17
  • OK, I think yeah its the issue with code itself. strong_params is what I was missing. – Abhinay Jan 08 '15 at 12:11
  • "The reason why your get request is working just fine is because rails doesn't expect authenticity_token on a GET request." but it is in this situation. without authentication token the response is "HTTP Token: Access denied" – Abhinay Jan 08 '15 at 12:14
  • Can you just add this code to your solution, along with your existing one. "def request_params params.require(:request).permit(:sender_mobile, :recipient_mobile, :location) end " – Abhinay Jan 08 '15 at 12:19
  • I think you are confused between `token` and `authenticity_token`. The `token` your passing is necessarily to validate the user and not the request and authenticity_token is to validate your request. – Pramod Solanky Jan 08 '15 at 12:23
  • Yeah adding request_params method and removing protect_from_forgery line from application controller solved the issue. – Abhinay Jan 08 '15 at 12:40
  • Can you help me understand the difference ? – Abhinay Jan 08 '15 at 12:46
  • I'm on mobile now .. Will continue chat in sometime – Pramod Solanky Jan 08 '15 at 12:47
  • Yes I will accept now. but I wont say it completely solved my problem, please add the code I have mentioned to your existing solution otherwise it will just create more reasons to put same question again. :) i hope you will edit your answer soon. thanks – Abhinay Jan 08 '15 at 12:53
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/68410/discussion-between-pamio-solanky-and-abhinay). – Pramod Solanky Jan 08 '15 at 13:08
  • Thanks for this solution. I had a similar problem and getting rid of `protect_from_forgery` solved it for me perfectly. – Evgenia Karunus Jan 08 '15 at 17:47