How can I perform basic authentication while using JSON? - json

I would like to access to a website with a lot of information and display all of it (as of now). However, I want to use JSON.parse and also authenticate the user and password in order to extract that information.
This is what I have:
require 'net/http'
require 'json'
url = 'http://robotrevolution.net/interface/int_order_options.php'
uri = URI(url)
response = Net::HTTP.get(uri)
jsonVal = JSON.parse(open(response))
puts jsonVal
However, while looking up online, I found I can use this:
require 'net/http'
require 'json'
require 'uri'
uri = URI('http://robotrevolution.net/interface/int_order_options.php')
Net::HTTP.start(uri.host, uri.port,
:use_ssl => uri.scheme == 'https',
:verify_mode => OpenSSL::SSL::VERIFY_NONE) do |http|
request = Net::HTTP::Get.new uri.request_uri
request.basic_auth 'username', 'password'
response = http.request request # Net::HTTPResponse object
puts response
puts response.body
end
Moreover, I would like to find a way to mix both of them and use automatic authentication as well as parse JSON at the same time. Thank you.

Consider using RestClient library (https://github.com/rest-client/rest-client).
Example:
require 'rest-client'
require 'json'
require 'ostruct'
url_endpoint = 'https://api.example.com'
basic_auth_user = 'user'
basic_auth_password = 'pass'
basic_auth_creds = "#{basic_auth_user}:#{basic_auth_password}"
response = RestClient.get(url_endpoint, {
Authorization: "Basic #{Base64::encode64(basic_auth_creds)}"
})
json = JSON.parse(response.body, object_class: OpenStruct) unless response.empty?

Related

How to send POST request using Julia lang HTTP library to a Django RESTFUL API (DRF)

There is very limited documentation when it comes to the HTTP library in Julia Lang. Not just that, but there are no up to date Stack Overflow questions regarding the HTTP library in general.
With that said, how do you send POST requests using Julia + HTTP to a Django Restful API (DRF)?
Julia 1.7, 1.8
If you are sending json formatted data (simple Django POST request):
begin
using JSON
using HTTP
const url = "http://127.0.0.1:8000/api/profile"
payload = Dict("email" => "email#email.com", "password" => "12345password")
response = HTTP.request(
"POST", url, ["Content-Type" => "application/json"], JSON.json(payload))
# this is necessary, JULIA discontinued python style Dictionaries
response = JSON.parse(String(response.body))
println(response)
end
If you are sending header information like Authentication tokens, etc.
begin
using JSON
using HTTP
const url = "http://127.0.0.1:8000/api/profile"
payload = Dict("email" => "email#email.com", "password" => "12345password")
access_token = "some access token"
headers = Dict(
"Content-Type" => "application/json",
"Authorization" => "Bearer $access_token")
response = HTTP.request(
"POST", url, headers, JSON.json(payload))
# this is necessary, JULIA discontinued python style Dictionaries
response = JSON.parse(String(response.body))
println(response)
end

Can't post JSON data to GitHub API (and probably others)

I'm using HTTP::UserAgent to try and use GitHub API from a program. Here's the program
use HTTP::UserAgent;
my $greeting = (%*ENV<BODY> ~~ /[Mm]erry/)??%*ENV<GREETING>!!%*ENV<HEY>;
my $url = "https://api.github.com/repos/JJ/raku-advent-calendar-article-2019/issues/%*ENV<ISSUE>/comments";
my %headers = Authorization => "token %*ENV<TOKEN>" ;
my %payload = body => $greeting;
my $agent = HTTP::UserAgent.new( useragent => "JJ's Xmas commenter" );
say $agent.post( $url, %payload,
Authorization => "token %*ENV<TOKEN>",
Content-Type => "application/json" );
If the content-type is not established, there's a malformed JSON error. If it's used, however, the error is different: 422 Unprocessable Entity. When using curl or similar, you can usually post directly the JSON string, but post in this case does not admit single strings, or if it's a form, I have no idea what to use as key. Can you please help?

HTTPS: 400 Bad request! Invalid JSON

I am trying to pass a POST method request for a specific URI using the Restclient gem. I am however, continously getting 400 Bad request from the server. I have tried numerous ways of posting the data, with modifications. PFB the current one
require 'minitest'
require 'rest-client'
require 'json'
require 'pry'
require 'uri/https'
#class APITest < Minitest::Test
def setup
response = RestClient.post("", {'userType' => 'nonsso', 'firstName' => 'Justin9', 'isDependentMajor' => true, 'email' => 'randomemail0053#gmail.com', 'dependentName'=> 'Cobb', 'dependentLastName' => 'Cobb', 'lastName' => 'Justin'
}, { "Content-Type" => 'application/json'})
puts response
end
setup
I am at a loss to understand what am I missing here. I tried using the same code, for an other api, with get method, only with headers and it works.
Please can someone let me know, any bad syntax in json I am using for the POST method.
response = RestClient.post("", {'userType' => 'nonsso', 'firstName' => 'Justin9', 'isDependentMajor' => true, 'email' => 'randomemail0053#gmail.com', 'dependentName'=> 'Cobb', 'dependentLastName' => 'Cobb', 'lastName' => 'Justin'
}.to_json, { "Content-Type" => 'application/json'})
Note the to_json.
RestClient serializes the payload in application/x-www-form-urlencoded by default. You have to manually serialize your post data.

Tornado POST request not detecting json input as argument

I have written a service which takes a json as input. I am using the website hurl.it to send post requests to check. Below is my code snippet:
class BatchSemanticSimilarityHandler(tornado.web.RequestHandler):
def post(self):
self.set_header('Access-Control-Allow-Origin', '*')
self.set_header('Access-Control-Allow-Credentials', 'true')
self.set_header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
self.set_header('Access-Control-Allow-Headers','Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token')
data = json.loads(self.request.body)
apikey = data["apikey"]
try:
UA = self.request.headers["User-Agent"]
except:
UA = "NA"
if bool(usercoll.find_one({"apikey":apikey})) == True:
sentence = data["sentence"]
sentence_array = data["sentence_array"]
n = data["num_of_results"]
if sentence is None or sentence_array is [] or apikey is None or n is None:
self.set_status(200)
output = {"error":[{"code":334,"message":"Bad Input data"}]}
misscoll.insert({"apitype":"batchsemanticsimilarity","timestamp":datetime.datetime.now(), "ip":self.request.remote_ip, "useragent":UA, "uri":self.request.uri,"apikey":apikey, "output":output, "input":{"s1":sentence,"s2":sentence_array}})
self.write(output)
return
results = nb.get_similar(sentence, sentence_array, apikey, n)
print "results is",results
output = {"similar_sentences": results, 'credits':'ParallelDots'}
hitscoll.insert({"apitype":"batchsemanticsimilarity","timestamp":datetime.datetime.now(), "ip":self.request.remote_ip, "useragent":UA, "uri":self.request.uri,"apikey":apikey, "output":output, "input":{"s1":sentence,"s2":sentence_array}})
self.write(output)
return
else:
rejectcoll.insert({"apitype":"batchsemanticsimilarity","apikey":apikey,"timestamp":datetime.datetime.now(), "ip":self.request.remote_ip, "useragent":UA, "url":self.request.uri})
self.write({"error":[{"code":333,"message": "Bad Authentication data"}]})
return
The json that I am giving as the body of the request is as below:
{
"sentence": "BJP leads in Bengaluru civic body`s poll, all eyes on JD(S)",
"sentence_array": [
"Narendra Modi is the prime minister",
"Sonia Gandhi runs Congress",
"Sachin is a good batsman"
],
"apikey": "DyMe1gSNhvMV1I1b20a7KARYIwuQX5GAQ",
"num_of_results": 2
}
I have verified on jsonlint that this is a valid JSON.
However while sending the request it gives me below error:
ValueError: No JSON object could be decoded
Can anyone please help me sort this out!!
The JSON object that you are passing in POST request is encoded into the url.
JSON library cannot read the encoded data.So you need to decode the url first.
Decoding of url can be done using urlparse library in python.so you need something like this.
post_data=urlparse.parse_qsl(self.request.body)
According to your need of final format to read there are various methods in urlparse.check this
or
As specified in the docs you can override a method to enable JSON parsing
def prepare(self):
if self.request.headers["Content-Type"].startswith("application/json"):
self.json_args = json.loads(self.request.body)
else:
self.json_args = None
check this

getting csrf tokens for json post requests to a rails app

I have been playing around with using rest-client to access a rails app I have written. I've written a quick script to log in and make a post request. Everything is working but I did have to work round the fact that no authenticity_token is served if you make a request for a form in json. I had to make a regular html request in other get the authenticity_token and then included this in the json I submitted as part of my post request. Basically I have a quick an dirty script like the one below
private_resource = RestClient::Resource.new( 'https://mysite.com')
params = {:user => {:email => 'user#mysite.com', :password => 'please'}}
#log in
login_response = private_resource['users/sign_in'].post(params, :content_type => :json, :accept => :json)
#get cookie
cookie = login_response.cookies
#get json
json_response = private_resource['products/new'].get(:content_type => :json, :accept => :json, :cookies => cookie)
#another request that returns html form with authenticity token
response_with_token = private_resource['products/new'].get( :cookies => cookie)
#extract token
token = Nokogiri::XML(response_with_token).css('input[name=authenticity_token]').first.attr('value')
#update cookie
cookie = response_with_token.cookies
#populate form and insert token
form = JSON.parse(json_response)
form['name'] = "my product"
form['authenticity_token'] = token
#submit the request
private_resource['products'].post(form.to_json, {:cookies => cookie, :content_type => :json, :accept => :json})
There is the option to turn off CSRF protection for json requests but I would rather not do that. I could go the mechanize route or something similar and then I wouldn't worry about json requests with CSRF but I just wanted to play around with doing this stuff with rest-client
I guess I'm just curious to know if there is a reason why no authenticity_token is served for json requests and I'm also wondering if there is a better way of solving the token problem than the pretty hacky approach I've taken here
Put the below code into your application controller :
def verified_request?
if request.content_type == "application/json"
true
else
super()
end
end
And call this method using before_filter .
For more details check :
http://blog.technopathllc.com/2011/09/rails-31-csrf-token-authenticity-for.html
And check this issue in rails : https://github.com/rails/rails/issues/3041
In your app/views/products/new.json.jbuilder, add this:
json.authenticity_token form_authenticity_token
This will insert a key "authenticity_token" with value being the token, so in your json_response you get the token as well. Idea from this answer.