Interpolation with httparty request in rails - ruby-on-rails

I want to make a http request (using httparty gem) to facebook graph to check if a token which comes form the client is valid or not, but I suppose that interpolation doesn't work with httparty
response = HTTParty.get("https://graph.facebook.com/me?access_token=#{params[:access_token]}")
render json: response
but this gives me the response
{"error":{"message":"Bad signature","type":"OAuthException","code":1}}
Am I missing something?

I suppose that interpolation doesn't work with httparty
Interpolation is a Ruby syntax feature; your string gets interpolated before it's ever passed to HTTParty.
You could have debugged this by inspecting the URL:
uri = "https://graph.facebook.com/me?access_token=#{params[:access_token]}"
Rails.logger.info(uri)
response = HTTParty.get(uri)
Regardless, when using query parameters with HTTParty, you shouldn't use interpolation anyway. You should pass them with the :query option, which will ensure that the parameters are encoded correctly:
response = HTTParty.get( "https://graph.facebook.com/me",
query: { access_token: params[:access_token] })
However, I'm not certain this will actually fix your problem. There's a good chance the problem is really somewhere else in your OAuth flow--there's a lot of room for error when working with OAuth.

Related

Ruby rest client array of params

I'm updating my rest-client gem from 1.8 to 2.0.
On 1.8 it sends an array of params on a get request as my-url?ids=1,2,3,4.
But on 2.0 it uses duplicated keys like my-url?ids=1&ids=2&ids=3. For reasons beyond the context of this question, our back end does NOT support the new multiple keys syntax (ok, it supports it, but we'll have to make a big refactor). So I'd like to know if there's a way to use the 2.0 client version and keep sending get array requests with only one key and separated by comma as before?
Based on the rest-client docs https://github.com/rest-client/rest-client#query-parameters it seems your only option would be to serialize the parameters yourself and add them to the URL as the query string.
If you don't like this behavior and want more control, just serialize params yourself (e.g. with URI.encode_www_form) and add the query string to the URL directly for GET parameters or pass the payload as a string for POST requests.
If you provide some sample code on how you're using the gem, we could help out a bit better with sample answers.
Ok yeah Leo Correa was right, so what I had to do is replace my old code
params = {
partner_key: #partner,
resources: ["front_end_config", "gui_settings"]
}
#response = JSON.parse( RestClient.get( "#{api_base_uri}/partner_config.json", params: params.merge({multipart:true}) ) )
with this new one, serializing and encoding by myself...
params = {
partner_key: #partner,
resources: '["front_end_config", "gui_settings"]'
}
params = URI.encode_www_form(params.merge({multipart:true}))
#response = JSON.parse( RestClient.get( "#{api_base_uri}/partner_config.json?#{params}" ) )
It's ugly as hell, but it worked for me. If there's some other idea on how to make it better, I'd appreciate.

HTTParty adding 25 to % in query string

I am creating a ruby on rails application using HTTParty. I create a request using this method
query = { :flyFrom => "london_gb",:dateFrom => "02%2F11%2F2015"}
response = HTTParty.get('https://api.blahblah.com/flights', :query => query)
However HTTParty seems to encode % signs as %25. So the request looks like this:
https://api.blahblah.com/flights?flyfrom=london&dateFrom==02%252F11%252F2015
As you can see the difference is:
02%2F11%2F2015
02%252F11%252F2015
My API expects the dates to be in a particular format, so is complaining about this. Does anyone know how you can get HTTParty to encode these characters correctly so that it sends just a % rather than %25?
Thanks.
Adjusted answer based on the additional comments.
"%25" is the correct URL encoding for "%". So HTTParty is encoding the percent.
However, "%2F" is the URL encoding for "/". So if you intend to send "02%2F11%2F2015" over the wire then you probably want to pass the unencoded version to HTTParty: "02/11/2015".

JSON parameters not available in request hash (Rails, omniauth-google-oauth2 gem)

Overview
I want to implement the Google OAuth2 server side (hybrid) with the Omniauth Google OAuth2 Gem (0.2.6). However, the code parameter I send to my app does not get added to the request.params hash. Thus, OmniAuth throws an error, as it can't find the code.
Details
After retrieving the auth code from Google I send it to the server (by AJAX):
// Send the code to the server
$.ajax({
type: 'POST',
url: '/auth/google_oauth2/callback',
contentType: 'application/json',
success: function(result) {
// Handle or verify the server response.
},
processData: false,
data: JSON.stringify(password_result)
});
This throws the error:
"error" : "invalid_request",
"error_description" : "Missing required parameter: code"
After going through the stack, I figured out the following:
As long as I have 'application/json' set as content Type, Rack parses the params correctly and the env object contains the parsed parameters:
"action_dispatch.request.request_parameters"=>{"code"=>"<sent_in_code>"}
However, the request.params hash remains empty. Since OmniAuth checks for request.params['code'], this is the source of the error.
request.POST is empty, which from looking at the source code of Rack is the underlying cause for the empty request.params hash.
When sending the code in standard format as data:"code="+authResult['code'], the parameter is available in the request.params hash. (I get a strange undefined route error then, but this is a different issue.)
Questions
Now, even though I can avoid the issue by not using JSON, I'm still very intereted in the answers to the following questions:
Why is the code parameter not available in request.POST/request.params, even though it gets parsed correctly?
Is there a way to fix this, so I can still send the auth code in JSON to my app?
I've spent two afternoons trying to get the answers myself, but haven't really gotten to a good conclusion so far.
omniauth-google-oauth2 tries to get the auth code from the Rack::Request.params hash. However, Rack apparently does not have JSON parsing built-in. Params calls POST which then calls form_data? which only looks for application/x-www-form-urlencoded or multipart/form-data. It then also tries parseable_data?, which does not parse JSON either. Seems like Rack does not support JSON out of the box, also look at this answer.
The "action_dispatch.request.request_parameters"=>{"code"=>"<sent_in_code>"} hash works because this is done by rails ActionDispatch::Request, which subclasses Rack::Request. However because The omniauth gem is included in your app as a Rack middleware, it does not know of the ActionDispatch request object.
The question remains why this example uses JSON.
Possible solutions:
money-Patch JSON Support into Rack - not recommended
just use application/x-www-form-urlencoded - recommended

HTTParty get request ignores query params

I'm trying to make a GET request with a quersytring, however, HTTParty is ignoring my params. For example, I'm doing something like this:
headers = {"User-Agent"=>"whatever", "Authorization"=>"whatever"}
options = {"sport" => "mlb" }
HTTParty.get("https://www.erikberg.com/events.json", query: options, headers: headers)
The response should be empty since yesterday there wasn't any MLB game going on. I checked with curl and worked properly. However, when I use this gem I'm getting NBA games (ignoring the param sport). I asked to the owner of the API and he told me I'm getting two redirects (302, 301).
Any clue of what is failing here? Is my request really using https?
Best regards!

Passing an attribute to a SOAP request using Savon

I'm consuming a simple SOAP web service to get a small piece of HTML to be included in a Rails site. Unfortunately, I'm not particularly familiar with SOAP.
I need to call the TopHtml() SOAP method on the endpoint below but I need to also pass an ID number like TopHtml(29).
I'm using the Savon gem and my code looks a little something like:
response = Savon::Client.new('http://www.xxxxxx.xxx/webservices/services.asmx?wsdl').top_html(29)
which works but returns the default response for when an ID number was not provided.
It seems that the ID number is not being passed. Does anyone know how to pass parameters to Savon SOAP requests?
Many thanks,
Tristan
try
response = Savon::Client.new('http://www.xxxxxx.xxx/webservices/services.asmx').top_html { |soap| soap.body = { :id => 29} }
In the interests of time, I ended up preparing the request XML myself which is less than ideal (and almost defeats the purpose of using Savon) but it's the only way I could have the request prepared properly. The XML was provided by the developers of the service.
client = Savon::Client.new 'http://www.xxxxxx.xxx/webservices/services.asmx?wsdl'
response = client.top_html do |soap|
soap.xml = ...long xml here...
end
Yuck but I'm not going to spend anymore time on it.

Resources