InvalidAuthenticityToken from rails for POST request
Hi All
I have a rails server running to which I make a POST request.
The dataset is defined as
Now per rails documentation in order to make a POST a request I need to set the add "authenticity_token" to the query string. So if for example the authenticity_token is "xxxxxxx", the final url should look like http://mywebsite.com/doSomething?aut..._token=xxxxxxx
I get the authenticity token from the server in the flashvars.
I have a user defined canvas attribute called auth_token which I use to store the authenticity token.
Below is the openlaszlo code I use to make the request.
var d = canvas.datasets.ds;
var content = get_my_content();
d.setQueryParam('lzpostbody',content);
d.setQueryString({authenticity_token : encodeURIcomponent(canvas.auth_token) });
d.doRequest
In this code the setQueryString call seem to clear out the query params. If I change the order of the setQueryString and setQueryParam calls the opposite happens.
The question is. Is there a way to set the query string without changeing/deleting the query params.
Thanks very much
Puneet
I don't know anything about OpenLaszlo, but my guess is that setQueryParam adds or modifies one param, whereas setQueryString overwrites the whole query string with the contents of the object.
Shouldn't you want to just add the authenticity token?
d.setQueryParam('lzpostbody', content);
d.setQueryParam('authenticity_token', encodeURIcomponent(canvas.auth_token));
Related
I have an old app running in rails 2.3.5
In customizing, I stuck when i find a param keyword being used in views
i.e in views I can see stuffs like
unless params[:fee_collection].nil?
can someone explain to me in what context is param keyword used in rail views rather than controllers
params is a hash that contains parameters sent with the HTTP request.
You can access to this object as well from your controller or from a view. Although, the convention is to access to an instance variable (defined in your controller, e.g : #fee_collection = params[:fee_collection]) from your view.
The params variable stores a hash which contains the http parameters received in the request to this route (controller#action)
If you have a UserController with the show method, you should receive the param[:id] to identify the resource you're looking for.
If you want to send parameters, it would be either via url in a GET or a data payload on a POST request, on the most common cases.
I'm getting a CORS POST request via OPTIONS sent to my app. It has no content-type set for the request.
It successfully gets to the right Controller action, but there is no accessible data. If I type params, there is nothing I can touch.
I did, however, discover that if I created Rack Middleware, and read the env['rack.input'], I could find all the data in the request I was looking for. So I wrote this :
env['CONTENT_TYPE'] = 'application/js'
rack_input = env['rack.input'].read
params = CGI::parse(rack_input).to_json
env['rack.input'] = StringIO.new params
env['rack.input'].rewind
status, headers, response = #app.call env
And magically, now in my controller, I can type params and see that ActionDispatcher successfully extracted the key/values from the request and make them accessible in my controller.
There's something suspicious about this. Is there are more appropriate way to extract OPTIONS requests and their respective data?
The OPTIONS call should not deal with data at all. It's a preflighted request to determine which actions are allowed using when using CORS.
RFC:
http://greenbytes.de/tech/webdav/rfc2616.html#rfc.section.14.7
The call will return with the allowed CORS HTTP verbs and a POST request should follow right after if POSTs are allowed on the server.
This is the way Rails accepts arrays in query parameters:
PUT /resource.json?sport_ids[]=133&sport_ids[]=64&sport_ids[]=71 ...
I tried to google this question but didn't find any explicit docs on it:
How to tell Rails that we want sport_ids to become empty (pass empty array of sport_ids via query parameters) ?
HTTP requests can have only variables on the url itself. That's a limitation feature of HTTP, not Rails.
Take a look at How Does Rack Parse Query Params? With Parse_nested_query to figure out how rails collects the variables into an array, it won't run out of the box in case of an empty array.
You can avoiding sending the params["sport_ids"] and patch your controller with:
params["sport_ids"] ||= []
The best practice to use put/post requests, is passing such data in the request body (json/xml) like:
{
"sport_ids": []
}
Or with data as:
//...
{
"sport_ids": [133, 64, 71]
}
//...
For more info about HTTP request steps, check Running a HTTP request with rails.
While #mohameddiaa27's answer has good advice on how to achieve that by passing such data in the request body as JSON I found that I cannot rely on it within my application: I found that it is not easy to combine such passing of JSON into request body within multipart forms where I want to pass user record (with user[sport_ids] in it) and user's avatar image (user[avatar]) field.
So I continued to investigate how to achieve that using default "query parameters in a request body of POST/PUT request" approach and found the reason why I was not able to reset my sport_ids on server-side: it was the lack of permission for that specific sport_ids field. Now I have the following permits (pseudocode):
current_user.update!(user_params)
where user_params is
user_attributes_to_permit = [
...
:sport_ids, # this is what was needed for just `user[sport_ids]` to work.
{ :sport_ids => [] } # this is needed for sport_ids non-empty arrays to work
...
]
params.require(:user).permit(user_attributes_to_permit)
so now I am able to reset the sport_ids array of my user by passing just user[sport_ids] (without '=' and value! i.e. ...&user[sport_ids]&...) within my query parameters.
I have a ruby on rails api where I want to sign my request data by appending a hashed version of all passed in parameters to the request and rebuild this one at the server side as well to validate the integrity of the requests.
When I simply use the params method in the controller I have different parameters (e.g. for an update-method which is specified by this:
put 'login' => 'login#update'
I get as parameters on the server:
{"timestamp"=>"1399562324118", "secured"=>"xxx",
"login"=>{"timestamp"=>"1399562324118", "secured"=>"xxx"}}
although I only send the request from the client with
{"timestamp"=>"1399562324118", "secured"=>"xxx"}
Does any one have an idea how to get rid of this "login" parameter in the params list in a generic way? I do not want to exclude this for every single request of my api.
Thanks a lot!
Per the Rails Edge guide on ActionController:
"If you've turned on config.wrap_parameters in your initializer or calling wrap_parameters in your controller, you can safely omit the root element in the JSON parameter"
See http://guides.rubyonrails.org/action_controller_overview.html#json-parameters
Is there a gem or easy way to validate a API post request? For example I am always expecting a field to be either present or always a string and if it is not to ignore the request all together.
Or is the only way to do this is to manually check each request coming in with an IF statement?
Once you get the request check the params in the controller and if the params are the way you need them to be allow post -> create/update your db records if not return nil to the post request.
I think you should assign a Model to your "request". This way you could "validate" presence of any given fields