golang passing data payload from HTTP client - api

I have an HTTPS endpoint that works fine with a cURL command like this:
curl -k -u xyz:pqr \
--data "grant_type=client_credentials" \
https://my-url
Now I am trying to use golang to call the same API endpoint like this:
data := url.Values{}
data.Set("grant_type", "client_credentials")
req, err := http.NewRequestWithContext(
ctx,
"POST",
"https://my-url",
strings.NewReader(data.Encode())
)
It fails with the error body:
{
"error_description":"grant_type is required",
"error":"invalid_request"
}
I am already passing grant_type as the last argument to the http.NewRequestWithContext() function.
What am I missing?

You are not translating the curl correctly. This tool might be helpful: https://mholt.github.io/curl-to-go/
Essentially you need to add user auth.
req.SetBasicAuth("xyz", "pqr")
// Might help to set the `Content-Type` too
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
-k on curl seems to be reading some curl arguments from a file too. You are going to want to make sure you translate those over as well. I cannot see what they are from your example.

Related

How can this curl command be converted to pycurl or python requests?

any hel pwill be highly appreciated. Just can't make this to work. I am basically trying to update my Grafana dashboard via a http request. managed to get it to work with curl but want to do this with python's requests or pycurl.
curl -X PUT https://<api token>#ks.hostedgraphite.com/api/v2/grafana/dashboards/<my_dashboard> --data-binary #dashboard.json
The command above works. Tried several ways, an example of a code snippet:
crl = pycurl.Curl()
crl.setopt(crl.URL,
'https://apitoken#ks.hostedgraphite.com/api/v2/grafana/dashboards/<my_dashborad>')
crl.setopt(crl.UPLOAD, 1)
file = open('dashboard.json')
crl.setopt(crl.READDATA, file)
crl.perform()
crl.close()
file.close()
print('Status: {}'.format(crl.getinfo(crl.RESPONSE_CODE)))
curl -X PUT https://api_token#ks.hostedgraphite.com/api/v2/grafana/dashboards/my_dashboard --data-binary #dashboard.json
translates to
import requests
data = open('dashboard.json', 'rb').read()
response = requests.put('https://api_token#ks.hostedgraphite.com/api/v2/grafana/dashboards/my_dashboard', data=data)
Just replace proper values for api_token and my_dashboard.
You can use https://curl.trillworks.com/ for converting curl commands to equivalent code using python requests.
ok, so my main issue was creating a http request via python requests.
Figured it out, I setthe auth param to auth=("graphite_api_token","") and it worked:
data = json.dumps(dashbord_dict)
headers = {"Accept": "application/json","Content-Type":"application/json"}
response =requests.put('https://ks.hostedgraphite.com/api/v2/grafana/dashboards/some_dashboard,auth=("graphite_api_token",""),data=data,headers=headers)
print(response.status_code)

Waste Management API - Authorization: Bearer problem

Im reading this documentation:
https://api.wm.com/howtotest/#make-an-api-call
And I want to make this test request in the postman:
curl -i https://apitest.wm.com/v1/helloworld \
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhbnlvbmVAYW55LmNvbSIsInN1YiI6Ildhc3RlIG1hbmFnZW1lbnQgIHRlYW0iLCJqdGkiOiIwQkQyRTVDQkM2RDE2Mzc0RkNFQSIsInNjb3BlIjpbInNlbGYiLCJoZWxsb3dvcmxkIl0sImlhdCI6MTQ5MDg5ODk1NSwiZXhwIjoxNTIyNDM0OTU1fQ.O2k-senypXFZQwW4Ln3mBg60qzOSo-diPQWVfir3m6Q" \
-H "ClientId: 0BD2E5CBC6D16374FCEA" \
-H "Request-Tracking-Id: 12132"
But i recived response like this:
{
"message": "'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhbnlvbmVAYW55LmNvbSIsInN1YiI6Ildhc3RlIG1hbmFnZW1lbnQgIHRlYW0iLCJqdGkiOiIwQkQyRTVDQkM2RDE2Mzc0RkNFQSIsInNjb3BlIjpbInNlbGYiLCJoZWxsb3dvcmxkIl0sImlhdCI6MTQ5MDg5ODk1NSwiZXhwIjoxNTIyNDM0OTU1fQ.O2k-senypXFZQwW4Ln3mBg60qzOSo-diPQWVfir3m6Q' not a valid key=value pair (missing equal-sign) in Authorization header: 'Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJhbnlvbmVAYW55LmNvbSIsInN1YiI6Ildhc3RlIG1hbmFnZW1lbnQgIHRlYW0iLCJqdGkiOiIwQkQyRTVDQkM2RDE2Mzc0RkNFQSIsInNjb3BlIjpbInNlbGYiLCJoZWxsb3dvcmxkIl0sImlhdCI6MTQ5MDg5ODk1NSwiZXhwIjoxNTIyNDM0OTU1fQ.O2k-senypXFZQwW4Ln3mBg60qzOSo-diPQWVfir3m6Q'."
}
This is the example of their official documentation, how it can be it doesnt works, or I didnt do something good?
I think that the error message is potentially misleading. If you are using the test example you need to request a clientid and token from WM per the documentation.
From the documentation:
With a valid access token and clientId, you are ready to make requests to Waste Management API.

What is -u from cURL when adding an authorization header to an http request

I am trying to test one of Mix Panel's API endpoints. I'm using Postman to do this, and in Mix Panel's documentation they use cURL to show you how to make the request. When entering the URL, and the POST data for the request, it works in the sense that it hits the right place, and tells me that I need to be authenticated by adding an authorization header. What I'm confused on is, what should the key be for the header ? in their cURL example its -u API_SECRET, so would the authorization header key be 'username' ?
From documentation
# this uses a test project API secret, replace ce08d087255d5ceec741819a57174ce5
# with your own API secret
curl https://mixpanel.com/api/2.0/jql \
-u ce08d087255d5ceec741819a57174ce5: \
--data-urlencode params='{"from_date":"2016-01-01", "to_date": "2016-01-07"}' \
--data-urlencode script='function main(){ return Events(params).groupBy(["name"], mixpanel.reducer.count()) }'
If I wanted to create an AJAX query for example
$.ajax({
method: 'POST',
url: 'https://mixpanel.com/api/2.0/jql',
data: {
'params': '{"from_date":"2016-01-01", "to_date": "2016-01-07"}',
'script': '\'function main(){ return Events(params).groupBy(["name"], mixpanel.reducer.count()) }\''
},
headers: {
<WHAT GOES HERE>: API_SECRET
}
}).then(function success(response){
console.log('SUCCESS');
console.log(response)
}, function error(response){
console.log('There was an error running JQL');
console.log(response.error)
});
In this case, your API_SECRET is the username and there is no password. So using curl -u <API_SECRET>: without any "username" key is correct.
From the mixpanel documentation on an example call https://mixpanel.com/help/reference/data-export-api
Authorization steps The Data Export API accepts Basic access
authentication over HTTPS as an authorization method. To make an
authorized request, put your project's API Secret in the "username"
field of the Basic access authentication header. Make sure you use
HTTPS and not HTTP - our API rejects requests made over HTTP, since
this sends your API Secret over the internet in plain text.
Examples Here's an example of a properly-authenticated request made
with cURL:
curl https://mixpanel.com/api/2.0/segmentation/ \
-u YOUR_API_SECRET: \
-d from_date="2016-02-11" -d to_date="2016-02-11" -d event="Viewed Page"

how to send correct curl command to webserver

So I got the data that is being sent to a specific server. Now I want to do the same using curl from my local machine to play around with specific repsonses from the server and learn more about curl as well.
Here is part of my data
POST /auth HTTP/1.1
platform: android
X-Auth-Token: <censored>
Content-Type: application/json; charset=utf-8
Host: api.blabla.com
Accept-Encoding: gzip
And the data that is being sent:
{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}
Now when I try cURL in my dos shell, I try
curl --insecure -X POST https://api.blabla.com/auth --data '{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}'
The response I get from cURL is this:
{"code":401,"error":"blablaTokenRequired"}
Even though I specified the token. So there are two possible scenarios because the token is correct:
It has something to do with the SSL thing? (I use --insecure because I get an SSL error otherwise)
Something about my command is not correct but I can't figure out what.
Can someone kindly help me out? I am trying everything I can without success
I am not sure if I understand your application specific right, but probably one thing you need to take into account:
man curl says:
-d, --data <data>
(HTTP) Sends the specified data in a POST request to the HTTP server, in the same way that a browser does when
a user has filled in an HTML form and presses the submit button. This will cause curl to pass the data to the
server using the content-type application/x-www-form-urlencoded. Compare to -F, --form.
-d, --data is the same as --data-ascii. --data-raw is almost the same but does not have a special interpreta‐
tion of the # character. To post data purely binary, you should instead use the --data-binary option. To URL-
encode the value of a form field you may use --data-urlencode.
As I can't see in your example the necessity of sending data as HTML form input, probably your application expects just a "raw" POST body and then you have to try this:
curl --insecure -X POST https://api.blabla.com/auth --data--binary '{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}'
PS and for sure this is error is not about using --insecure which just asks curl to neglect ssl verification
you forgot the headers and enabling compressed encoding (gzip), however, i believe you can't force curl to only support gzip encoding using the curl command line alone, you will have to use libcurl, this will make the request say "Accept-Encoding: gzip,deflate" on most systems, using --compressed .. if that's not acceptable to you, rewrite it using libcurl (where you can force it to say only "gzip", if you wish, via CURLOPT_ENCODING )
curl -X POST https://api.blabla.com/auth --data '{"blabla_token": "sdsadsad", "blahblah_id": "23213", "locale": "us"}' --header 'platform: android' --header 'X-Auth-Token: <censored>' --header 'Content-Type: application/json; charset=utf-8' --header 'Host: api.blabla.com' --compressed
another gotcha: on some systems, there will be a default useragent header (like debian 6), while on some systems, curl comes without a default useragent (like debian 8).. you might want to use --user-agent '' too

Pushbullet API from cURL - invalid request

I'm working on an app using Pushbullet's API, but I'm running into odd errors when running through the sample code at https://docs.pushbullet.com/v2/pushes/.
I'm executing the following cURL command (in Windows):
curl -k -u <MY_API_KEY>: -X POST https://api.pushbullet.com/v2/pushes --header 'Content-Type: application/json' --data-binary '{"type": "note", "title": "Note Title", "body": "Note Body"}'
...but it keeps generating the following error:
{"error": {"type":"invalid_request","message":"The param 'type' has an invalid value.","param":"type","cat":"\u003e:3"}}
It also produces this error:
The other commands for the other endpoints in the documentation work fine...it's just this one.
Got any suggestions? Thanks for the help! :)
It looks like windows doesn't support those kinds of quotes on the command line. Here's an example that works:
curl https://api.pushbullet.com/v2/pushes -X POST -u <access token>: --header "Content-Type: application/json" --data-binary "{\"type\": \"note\", \"title\":\"Note Title\", \"body\": \"Note Body\"}"
I think I'm going to try to replace the curl examples with something that has less confusing behavior.
I figured it out - I don't really know why, but the cURL command wasn't working through the DOS prompt, and also wasn't working using the Postman REST client for Chrome, but I got it working in the DHC extension for Chrome. The trick was setting the Authorization header to "Basic", which resolves the Pushbullet access token to some other form, and makes a successful the HTTP request.
Hope this helps someone down the road if they run into this on Windows!