Ruby - HTTPS get calls with headers - ruby

Have a query on making a https Get call with headers. I tried the following
uri = URI.parse("https:\\www.someurl.com")
req = Net::HTTP::Get.new(uri)
# Following is where I am adding the header
req['Auth'] = "Bearer" + #token
response = Net::HTTP.start(uri.host,uri.port) do |http|
request = Net::HTTP::Get.new uri.request_uri
http.request request
end
puts(response.body)
I see the following error
400 The plain HTTP request was sent to HTTPS port
I tried searching and what I have found is that Net::HTTP.get supports https calls but without headers.
The call that I am making is via API gateway, so I will have to add a token in the header.
Any help is much appreciated. Thanks in advance.

You need to use use_ssl: true.
uri = URI('https://secure.example.com/some_path?query=string')
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Get.new(uri)
request['Authentication'] = "Bearer %s" % #token
http.request(request)
end

Related

Unauthorized readbody=true when posting message to hangout chat room with webhook

Trying to post a message to a hangout chat room. I've generated a webhook for the room and used it as uri in the following code. The rest are basic net/http stuff.
require 'net/http'
require 'uri'
message = 'hello'
# prep and send the http request
uri = URI.parse("https://chat.googleapis.com/v1/spaces/AAAAcroWtl4/messages?key=abc&token=xyz")
request = Net::HTTP::Post.new(uri)
request.content_type = "application/json"
request.body = '"content":[{"type":"text","text":"'+message+'"}]'
req_options = { use_ssl: uri.scheme == "https" }
response = Net::HTTP.start(uri.hostname, uri.port, req_options) do |http|
http.request(request)
end
puts response.inspect
The response contains the following text.
#<Net::HTTPUnauthorized 401 Unauthorized readbody=true>
Is there something wrong with the request body?
Edit: key and token changed in the question.
This same code worked with stride rooms, the only difference is that it had
request["Authorization"] = "Bearer #{access_token}"
Since the token is already in the uri I figured this would not be needed.
This worked for me
require 'net/http'
require 'uri'
require 'json'
message = 'hello'
# prep and send the http request
uri = URI.parse("//webhook")
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = "application/json"
request.body = { text: message }.to_json
response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
http.request(request)
end
puts response.inspect

Trying to make HTTP Post request with a body using Ruby HTTP start block

I'm trying to make a POST request with basic oauth and a body param.
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) do |http|
request = Net::HTTP::Post.new(uri)
request['Authorization'] = 'ACCESS_CODE'
request.body = {
to: to,
subject: subject,
text: text,
api_type: 'json',
uh: #modhash
}.to_json
http.request(request)
end
It returns a
<Net::HTTPOK 200 OK readbody=true>
so I know the oauth is working but the body param is not getting passed into the request because it is returning this error
[".error.NO_USER.field-to"]], ["please enter a username"]]
I checked all the data values in the body hash and none of them are null.
Use the set_form_data method to set your POST body:
Here is an example from the docs:
request = Net::HTTP::Post.new(uri)
request.set_form_data('from' => '2005-01-01', 'to' => '2005-03-31')

Ruby Sinatra create post request without PEM and OpenSSL::SSL::VERIFY_NONE

I try create POST request with SSL but without OpenSSL::SSL::VERIFY_NONE because it is opend up security attacks and without PEM certificate.
But I catch problems, my ruby code for send POST request:
post '/test/test1' do
cross_origin
post_data = request.body.read
res_Data = JSON.parse(post_data)
userName = res_Data['username']
#responseFromServer=''
uri = URI('https://test.com/test1')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Post.new uri.request_uri
request.basic_auth 'aa', 'bb'
request.body = {'username' =>userName}.to_json
response = http.request request
#responseFromServer = response.body.to_s
end
newJson = JSON.parse(#responseFromServer)
status_msg = newJson['status']['status_msg']
if (status_msg == "Success")
return 'true'
end
return 'false'
end
It is method worked but he use OpenSSL::SSL::VERIFY_NONE. How to create method for send POST request without OpenSSL::SSL::VERIFY_NONE and PEM sertificate?
EDIT
SSL/HTTPS request
Update: There are some good reasons why this code example is bad. It introduces a potential security vulnerability if it's essential you use the server certificate to verify the identity of the server you're connecting to. There's a fix for the issue though!
require "net/https"
require "uri"
uri = URI.parse("https://secure.com/")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request)
response.body
response.status
response["header-here"] # All headers are lowercase
SSL/HTTPS request with PEM certificate
require "net/https"
require "uri"
uri = URI.parse("https://secure.com/")
pem = File.read("/path/to/my.pem")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.cert = OpenSSL::X509::Certificate.new(pem)
http.key = OpenSSL::PKey::RSA.new(pem)
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
request = Net::HTTP::Get.new(uri.request_uri)
My question: How to create POST method without PEM and OpenSSL::SSL::VERIFY_NONE?
This question is quite misleading, but I try my best to figure it out. Here is my advise:
Do you want to connect to a service that is only available through https and you do not care if the certificate is valid?
Then you can use :verify_mode => OpenSSL::SSL::VERIFY_NONE when initializing the Net::HTTP client.
You will have some kind of transport security, but you cannot be sure the server you are talking to is the one you think it is. You are vulnerable.
Do you want to connect to a service that is available both through https and http, and you do not care about transport security?
Then you should use the http://... endpoint.
Do you want to connect to a service and you care about transport security?
Then you should definitely use the https://... endpoint.
Do not override :verify_mode!
If you are getting certificate verification errors, make sure you have the correct Certificate Authority installed on your system.

Microsoft Live authorization GET request returns Net::HTTPBadRequest 400

I am following Microsoft live connect API documentation to authorize my user to access onedrive. I am trying to stablish code flow authentication. I got the AUTHORIZATION_CODE as described. Now, I am trying to get the ACCESS_TOKEN with the help of that:
In Microsoft live connect API documentation, its said for getting ACCESS_TOKEN we need to provide a request such as,
POST https://login.live.com/oauth20_token.srf
Content-type: application/x-www-form-urlencoded
client_id=CLIENT_ID&redirect_uri=REDIRECT_URI&client_secret=CLIENT_SECRET&
code=AUTHORIZATION_CODE&grant_type=authorization_code
I provided the same request using ruby and got a error:
#<Net::HTTPBadRequest 400 Bad Request readbody=true>
Then I found in microsoft forum, that the request is GET not POST.
so, I created a GET request in ruby as follow:
access_code =params["code"]
uri = URI.parse("https://login.live.com/oauth20_token.srf")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true if uri.scheme == 'https'
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
http.read_timeout = 500
req = Net::HTTP::Get.new("https://login.live.com/oauth20_token.srf",
initheader = {'Content-Type' =>'application/x-www-form-urlencoded'})
data = URI.encode_www_form({'client_id'=> 'my_client_id' ,
'redirect_uri' =>'my_redirect_url',
'client_secret' =>'my_client_secret',
'code'=>access_code, 'grant_type' =>'authorization_code'})
req.body = data
res = http.start { |http| http.request(req) }
When I run this I am getting the same HTTPBadRequest 400 error.
Note: I have checked the values of CLIENT_ID,REDIRECT_URI,CLIENT_SECRET,AUTHORIZATION_CODE it's all perfect.
I regret seeing that forum to solve this problem and wasted my time.
actually POST request will do good in this situation as show in thier documentation.
This is how I got the response,
uri = URI.parse("https://login.live.com/oauth20_token.srf")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Post.new("https://login.live.com/oauth20_token.srf")
req.content_type = "application/x-www-form-urlencoded"
data = URI.encode_www_form({'client_id'=> 'my_client_id' , 'redirect_uri' =>'my_redirect_ui', 'client_secret' =>'my_client_secret', 'code'=>access_code, 'grant_type' =>'authorization_code'})
req.body = data
response = http.request(req)

Ruby httpclient url

I am making a call to a webservice via HTTPClient ruby gem. The location doesn't matter, but let's say it is at: https://mywebservice.com/api/v1/accounts/login/
When I send a post request:
url = "https://mywebservice.com/api/v1/accounts/login/"
client = HTTPClient.new
client.post url
I get a 404 response, that the page was not found. I setup a proxy and checked out exactly what was being sent it seems like the gem is messing up the url, it actually sends the request to:
https://mywebservice.comhttps://mywebservice.com:443/api/v1/accounts/login/
I am completely lost, I have no why it is doing that. Does it have anything to do with the fact that it's https and I should handle https differently?
Thanks
Yes, if you are requesting a https url do this:
require 'net/http'
require 'net/https'
require 'uri'
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri.request_uri)
#you need to set this field to true
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
response = http.request(request)
Here is a link that should help:
http://bibwild.wordpress.com/2012/04/30/httpclient-is-a-nice-http-client-forin-ruby/
You should post to an uri with a body of params. Something like
client.post "http://mysite.com:8080", data
where data is a hash with the required parameters for the page.
For instance:
data = {"var" => "var"}

Resources