Net::HTTP.post_form cannot send parameter - ruby-on-rails

Hi I'm using rails and socket.io in node.js What I'm trying to do is send a param in rails model using Net::HTTP.post_form and get the param in node.js file which is server.js
model send.rb
def self.push(userid)
url = "http://socket.mydomain.com/push"
res = Net::HTTP.post_form(URI.parse(URI.encode(url)),data)
end
server.js
app.post('/push', function (req, res) {
console.log(req.param.userid)
});
req variable
req.ip =127.0.0.1
req.protocol= http
req.path = /push
req.host = socket.mydomain.com
req.param
I printed all the values but param always empty is there any solution for this? thanks in advance! :D

In Express you can retrieve values posted (HTTP POST) in an HTML form via req.body.searchText if you issue use app.use(express.bodyParser()); Notice that HTML form values come in req.body, not req.params.
Having said that, I am not sure how these values are submitted to the server when you use Socket.io rather than a "normal" HTTP POST on an HTML form.
I realize this is not an exact answer to your question, but wanted to mention how "normal" HTML form values are handled in case it helps and this was way to long to include as a comment.

Related

ruby-saml SAMLRequest as POST instead of GET

I am starting to use ruby-saml for one of the projects. IDP that I am using is expecting POST for authentication request with HTTP body containing SAMLRequest. Looking at the source code for authrequest.rb, create method can only do GET instead of POST.
I decided to call the create_params and get the base64 token which I can use from my view to do a POST.
When I use the following code
params = {}
request = OneLogin::RubySaml::Authrequest.new
token = request.create_params(saml_settings, params)
p token
p token["SAMLRequest"]
p decode(token["SAMLRequest"])
When i try base64decode.org or call the decode method, I get encoding for is not correct.
1) Can I do a POST instead of a GET?
2) What am I doing wrong in creating the request for it to be bad encoding?
thanks
1) Can I do a POST instead of a GET?
Yes, but support POST-binding is not just replace GET parameters by POST parameters...the signature on POST-binding is embed on the SAML message and is not another GET parameter.
2) What am I doing wrong in creating the request for it to be bad encoding?
thanks
The AuthNRequest is not only base64encoded, but also deflated.
Try use Base64 Decode + Inflate
You will find that thread interesting:
https://github.com/onelogin/ruby-saml/issues/124

Swapping Rails 4 ParamsParser removes params body

I'm trying to follow this solution to add a params parser to my rails app, but all that happens is that I now get the headers but no parameters from the body of the JSON request at all. In other words, calling params from within the controller returns this:
{"controller"=>"residences", "action"=>"create",
"user_email"=>"wjdhamilton#wibble.com",
"user_token"=>"ayAJ8kDUKjCiy1r1Mxzp"}
but I expect this as well:
{"data"=>{"type"=>"residences",
"attributes"=>{"name-number"=>"The Byre",
"street"=>"Next Door",
"town"=>"Just Dulnain Bridge",
"postcode"=>"PH1 3SY",
"country-code"=>""},
"relationships"=>{"residence-histories"=>{"data"=>nil},
"occupants"=>{"data"=>nil}}}}
Here is my initializer, which as you can see is almost identical to the one in the other post:
Rails.application.config.middleware.swap(
::ActionDispatch::ParamsParser, ::ActionDispatch::ParamsParser,
::Mime::Type.lookup("application/vnd.api+json") => Proc.new { |raw_post|
# Borrowed from action_dispatch/middleware/params_parser.rb except for
# data.deep_transform_keys!(&:underscore) :
data = ::ActiveSupport::JSON.decode(raw_post)
data = {:_json => data} unless data.is_a?(::Hash)
data = ::ActionDispatch::Request::Utils.deep_munge(data)
# Transform dash-case param keys to snake_case:
data = data.deep_transform_keys(&:underscore)
data.with_indifferent_access
}
)
Can anyone tell me where I'm going wrong? I'm running Rails 4.2.7.1
Update 1: I decided to try and use the Rails 5 solution instead, the upgrade was overdue anyway, and now things have changed slightly. Given the following request:
"user_email=mogwai%40balnaan.com
&user_token=_1o3Kpzo4gTdPC2bivy
&format=json
&data[type]=messages&data[attributes][sent-on]=2014-01-15
&data[attributes][details]=Beautiful+Shetland+Pony
&data[attributes][message-type]=card
&data[relationships][occasion][data][type]=occasions
&data[relationships][occasion][data][id]=5743
&data[relationships][person][data][type]=people
&data[relationships][person][data][id]=66475"
the ParamsParser middleware only receives the following hash:
"{user":{"email":"mogwai#balnaan.com","password":"0h!Mr5M0g5"}}
Whereas I would expect it to receive the following:
{"user_email"=>"mogwai#balnaan.com", "user_token"=>"_1o3Kpzo4gTdPC2b-ivy", "format"=>"5743", "data"=>{"type"=>"messages", "attributes"=>{"sent-on"=>"2014-01-15", "details"=>"Beautiful Shetland Pony", "message-type"=>"card"}, "relationships"=>{"occasion"=>{"data"=> "type"=>"occasions", "id"=>"5743"}}, "person"=>{"data"=>{"type"=>"people", "id"=>"66475"}}}}, "controller"=>"messages", "action"=>"create"}
The problem was caused by the tests that I had written. I had not added the Content-Type to the requests in the tests, and had not explicitly converted the payload to JSON like so (in Rails 5):
post thing_path, params: my_data.to_json, headers: { "Content-Type" => "application/vnd.api+json }
The effects of this were twofold: Firstly, since params parsers are mapped to specific media types then withholding the media type meant that rails assumed its default media type (in this case application/json) so the parser was not used to process the body of the request. What confused me was that it still passed the headers to the parser. Once I fixed that problem, I was then faced with the body in the format of the request above. That is where the explicit conversion to JSON is required. I could have avoided all of this if I had just written accurate tests!

Desire2Learn Valence API | JSON not loading

I'm using the Python Requests library with the Valence-provided Python SDK to attempt to do a GET request. Something odd is happening with the URL and I'm not sure what. The response I get is 200 (which leads me to believe that the authentication is working), but when I try to print the JSON from the Request object, it instead prints the HTML of the page instead of the JSON.
I'm using modified code that I read from http://docs.valence.desire2learn.com/clients/python/auth.html.
Here's the Python code:
import requests
import auth as d2lauth
from auth import *
app_creds = { 'app_id': '----', 'app_key': '----' }
ac = d2lauth.fashion_app_context(app_id=app_creds['app_id'], app_key=app_creds['app_key'])
auth_url = ac.create_url_for_authentication('ugatest2.view.usg.edu', 'http://localhost:8080')
redirect_url = "https://localhost:8080?x_a=3----&x_b=3dMRgCBAHXJDTA2E6DJIfdWq-gYl-pk77fF_3X5oDUuqc"
uc = ac.create_user_context(auth_url, 'ugatest2.view.usg.edu', True)
route = 'ugatest2.view.usg.edu/d2l/api/versions/'
url = uc.create_authenticated_url(route)
r = requests.get(url)
print(r.text)
The output is the HTML of a page instead of JSON. If I do print(r), I get a status of 200. I think my redirect URL may be the issue, but I'm not sure what exactly is wrong. Thanks for any help!
Two things look off to me:
Using auth_url to create a user context isn't going to work, that's the URL you need to send the user to so they can authenticate. You need to use the URL you were redirected to after authenticating to build the user context. Assuming redirect_url is that URL, you should be passing that to create_user_context and not auth_url.
ugatest2.view.usg.edu/d2l/api/versions/ is not a valid value for passing to create_authenticated_route, /d2l/api/versions is probably what you want. The SDK will prepend the scheme, domain, and port so including those in the value passed is going to result in an incorrect URI.
Once your app is working properly, you'll be able to access a JSON response by using r.json() rather than r.text.

Ruby - how to get parameters if the request is a post that sends in JSON

I have this request that comes in like this:
Parameters: {"kpi"=>{"action"=>"create", "users"=>[{"las_name"=>"Doe", "user_id"=>"123", "first_name"=>"John"}, {"las_name"=>"Smith", "user_id"=>"456", "first_name"=>"Anna"}, {"user_id"=>"789", "last_name"=>"Jones", "first_name"=>"Peter"}], "controller"=>"api/kpis"}, "users"=>[{"las_name"=>"Doe", "user_id"=>"123", "first_name"=>"John"}, {"las_name"=>"Smith", "user_id"=>"456", "first_name"=>"Anna"}, {"user_id"=>"789", "last_name"=>"Jones", "first_name"=>"Peter"}]}
but it comes as JSON in a POST request so I am not sure how to get it into a local variable.
Any idea how to do that?
Thanks!
The fact that the parameters are showing up like that means that your create action is properly set up to handle JSON as a transport mechanism. Based on that snippet, you can access these parameters via the params hash.
kpi = params[:kpi]
#users = kpi["users"]

XMLHttpRequest Post Method - Headers are stopping function

I'm trying to send an XMLHttpRequest object to my Rails server but the headers are causing my function to stop. Here are my observations:
When I comment out the 3 lines of code that set the headers, then xhr.readyState will eventually equal 4 (alert boxes within the anonymous function fire off).
If any one of the 3 header lines are uncommented, then the xhr object never changes state (none of the alert boxes ever fire off).
function saveUserProfile(){
var user_email = $('#userEmail_box').val();
var xhr = new XMLHttpRequest();
xhr.onreadystatechange=function(){
if (xhr.readyState==4 && xhr.status==200)
{
alert("Yes: " + xhr.readyState);
}
alert("No: " + xhr.readyState);
}
var method = 'POST';
var params = 'userEmail=user_email';
var url = 'http://localhost:3000/xhr_requests.json';
var async = true;
//Need to send proper header information with POST request
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-length', params.length);
xhr.setRequestHeader('Connection', 'close');
xhr.open(method, url, async);
xhr.send(params);
}
My three questions are:
What do I need to change in the code above in order to send data through the POST method?
I'm under the impression that the POST method requires some headers to be sent but am not clear about which ones though "xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');" seems to be one that is often mentioned in references. Can somebody help me understand a) why headers need to be sent and b) which ones need to be sent?
I'm using a rails server and am developing locally. Ultimately, this code will be executed on the client side of a mobile device which will go to a hosted rails server for passing and receiving data. Are there limitations with using the POST method with a rails server? Keep in mind that I plan to use JSON when sending information to the client from the server.
Thanks!
UPDATE: The headers should come AFTER the opening the xhr request but BEFORE sending it:
xhr.open(method, url, async);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-length', params.length);
xhr.setRequestHeader('Connection', 'close');
xhr.send(params);
Hope this post saves somebody else 4 hours.
Does your web page with the JavaScript code also live on localhost:3000? If not, this is considered a cross-domain request, and your server will need to return special headers. So you have two options:
1) Host the web page on the same domain as the server, which will make this a same-domain request.
2) Have your server return the appropriate CORS headers. You can learn more about CORS here: http://www.html5rocks.com/en/tutorials/cors/

Resources