API 1.1 requesting twitter bearer token using r - r

I have searched this forum and tried several things that seemed relevant, but with no success. If anyone can spot what I'm missing I would be very grateful.
I am trying to get a bearer token using application only authorization as explained at https://dev.twitter.com/docs/auth/application-only-auth so that I can GET follower s/ids.
I have constructed a request in r using rstudio with my consumer key & secret in Base64 encoded form.
library(httr)
POST(url="https://api.twitter.com/oauth2/token", config=add_headers(
c('Host="api.twitter.com"',
'User-Agent="NameOfMyApp"',
'Authorization="Basic MyKeyandSecretBase64Encoded"',
'Content-Type="application/x-www-form-urlencoded;charset=UTF-8"',
'Content-Length="29"',
'Accept-Encoding="gzip"')), body="grant_type=client_credentials")
In response I receive:
Response [https://api.twitter.com/oauth2/token]
Status: 403
Content-type: application/json; charset=utf-8
{"errors":[{"label":"authenticity_token_error","code":99,"message":"Unable to verify your credentials"}]}
I tried resetting my credentials but it made no difference.

I'm a few weeks late, but for anyone like me who stumbles across this page, here is some code that works for me, returning a bearer token:
POST(url="https://api.twitter.com/oauth2/token",
config=add_headers(c("Host: api.twitter.com",
"User-Agent: [app name]",
"Authorization: Basic [base64encoded]",
"Content-Type: application/x-www-form-urlencoded;charset=UTF-8",
"Content-Length: 29",
"Accept-Encoding: gzip")),
body="grant_type=client_credentials")
Once you have a bearer token, you put it in the header of a GET like so:
GET("https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=justinbieber&count=5000",
config=add_headers(c("Host: api.twitter.com",
"User-Agent: [app name]",
"Authorization: Bearer [bearer token]",
"Accept-Encoding: gzip")))

A late response, but the existing answer wasn't working for me. So here's a solution with a modification of the GET request.
add_headers() uses a named vector. This requires the hyphenated header names to be bracketed with backticks (``). So your POST() call should be:
response <- POST(url = "https://api.twitter.com/oauth2/token",
config = add_headers(.headers = c(Host = "api.twitter.com",
`User-Agent` = "NameOfMyApp",
Authorization = "Basic [base64encoded]",
`Content-Type` = "application/x-www-form-urlencoded;charset=UTF-8",
`Content-Length` = "29",
`Accept-Encoding` = "gzip")),
body = "grant_type=client_credentials")
Within a successful response the application access token can be accessed with:
bearer_token <- jsonlite::fromJSON(rawToChar(response$content))$access_token
You can then verify this with a GET request, such as:
GET("https://api.twitter.com/1.1/followers/ids.json?cursor=-1&screen_name=justinbieber&count=100",
config = add_headers(.headers = c(Host = "api.twitter.com",
`User-Agent` = "NameOfMyApp",
Authorization = paste("Bearer", bearer_token),
`Accept-Encoding` = "gzip")))

Related

Getting 401 error from Post request in R with Bearer token

Im trying to update a body on a postman POST which ask for Bearer Token (that I have) but still getting 401 error..
I first request the Token
login <- list(
"corporateEmail" = " xxx#xxx.com",
"password" = "xxx"
)
test <- httr::POST("https://xxxx", body = login, encode = "json")
and succesfully the the access token in the response.
then trying to do the post to change the body
test2 <- httr::POST(url = urls,
add_headers(Authorization = token),
body = bodys,
encode = "json",
verbose())
and i get 401...
the body is correct and I have tryed with Authorization = paste("Bearer",token)... the Postman configuration of the request is that Bearer is add in Auth tab and not directly in the Header tab.
Post request, expecting 200 answer

How to send basic authorization header with Python3.6.9 urllib3

I am trying to send an API call to get the time from the Questrade platform. Here is the sample request from their guide
GET /v1/time HTTP/1.1
Host: https://api01.iq.questrade.com
Authorization: Bearer C3lTUKuNQrAAmSD/TPjuV/HI7aNrAwDp
I am able to get it working with the request module
headers = {'Authorization': f'{token_type} {access_token}'}
print(headers) -> {'Authorization': 'Bearer -xSoUNCLYCrFjxxxxx_wAQVpi4olWrQs0'}
qt_time_obj = requests.get(api_server + 'v1/time', headers=headers)
qt_time = qt_time_obj.json()['time']
print(qt_time) -> 2020-10-13T17:06:32.388000-04:00
Now I am trying to get urllib3 to work but without luck
headers = {'Authorization': f'{token_type} {access_token}'}
url = api_server + 'v1/time'
http = urllib3.PoolManager()
qt_time_obj = http.urlopen('GET', url, headers)
print(qt_time_obj.status) -> 401
print(qt_time_obj.data) -> b'{"code":1014,"message":"Missing authorization header"}'
I also tried with the make_headers method but it gives me the same error.
headers = urllib3.make_headers(basic_auth="Authorization: Bearer AdKt3YUl46_tGnZp7cRgTu4W2vtfBME50")
Could you point where I did wrong? Thank you!
So after some trying, I found that I need to use http.request instead of the http.open. I also need to do "headers=headers" instead of just the "headers" in the method.
qt_time_obj = http.request('GET', url, headers=headers)

Posting a file to an outside API with a JSON web token

I am trying to upload a database file to an outside organization's API using R. I have a username and password, as well as an separate address to get the token from, and then to upload the file.
usr<-"username"
pw<-"passwood"
url <- "https:/routurl/api/"
Token='Token'
UploadFile='UploadFile'
#Get Token
r <- httr::POST(url = paste0(url,Token),
body = list(
UserName = usr,
Password = pw,
grant_type = "password"
), verbose())
tkn=jsonlite::prettify(httr::content(r, "text"))
This seems to work, as I can extract a token from the content.
> tkn
{
"result": {
"token": "eyJhbGciOiJIUzFAKEIsInR5cCI6IkpCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiZ3JphzZSIsImp0aSI6IjUwNmIwN2MyLTTHISISFAKEIwMDUvMDUvaWRlbnRpdHkvY2xhaW1zL2VIVECHANGEDTHINGScyI6ImVtaWx5dGdyaWZmaXRoc0BiaW9zLmF1LmRrIiwiZXhwIjoxNTk4NzEwMTU3LCJpc3MiOiJ2bXNhcHAiLCJhdWQiOiJ2bXN1c2VycyJ9.z8sr-HT21u1bN7qCEXAMPLEONLY-TKAluO3k",
"expiration": "29 August 2020 16:09:17"
},
"id": 2,
"exception": null,
"status": 5,
"isCanceled": false,
"isCompleted": true,
"isCompletedSuccessfully": true,
"creationOptions": 0,
"asyncState": null,
"isFaulted": false
}
#re-formatting
tkn=jsonlite::fromJSON(content(r, "text"), simplifyVector = FALSE)
So, this all seems ok, however, if I try to double check this on the JSON DeCoder, my correct web information comes up in the payload, but at the bottom it claims it is an invalid signature.
Also, the auth_token variable is NULL in the request, and that doesn't seem right.
> r$request$auth_token
NULL
However, I can't test this because I cannot, for the life of me, figure out how to use this JWT to POST a file to the rooturl/UploadFile. Every document I look at that goes over how to POST to an API does not include how to include your JWT in the POST, or at least it isn't very clear. Is it in the header? Is it like this?
r2=POST(url=paste0(url,UploadFile), body = list(y = upload_file('O:/Igoturfilerighthere.h5')),
add_headers('Authorization' = paste("Bearer", tkn$result$token, sep = " ")), encode = "json", verbose())
Am I setting the headers incorrectly?
r3=POST(url=paste0(url,UploadFile), body = list(y = upload_file('O:/Igoturfilerighthere.h5')),
httr::add_headers("x-auth-token"=tkn$result$token), verbose())
For the r3 request I get a 401 error, which makes me think that I am on the correct path and that I am entering my token information incorrectly. If anyone could help guide me on the next step, I'd appreciate it. I just don't know where else to place that information.
Cheers,
etg
UPDATE:
If, in the initial request, I add 'encode = "json"', it throws a 400 Bad Request Error. This is how the website I am trying to upload to writes its own code. I've double checked my username and password, and they are correct.
r <- httr::POST(url = paste0(url,Token),
body = list(
UserName = usr,
Password = pw,
grant_type = "password"
),encode = "json", verbose())
HTTP/1.1 400 Bad Request
Transfer-Encoding: chunked
Content-Type: application/problem+json; charset=utf-8
Server: Microsoft-IIS/10.0
Strict-Transport-Security: max-age=2592000
X-Powered-By: ASP.NET
So, I reached out to the org behind the API I was trying to access, and there few a few problems with my JWT request. This is the correct code:
r <- httr::POST(paste0(url,Token),
body = list(UserName = usr, password = pw),
encode = "form", verbose())
The big difference is 'grant_type' is removed and 'encode="form"', as I was trying to log in via a form on their site. With that difference, I was able to upload a file using the following:
r2=POST(url=paste0(url,UploadFile), body = list(fileToUpload = httr::upload_file('O:/IGotUrFileHere.h5')),
httr::add_headers('Authorization' = paste("Bearer", tkn$result$token, sep = " ")), verbose())
Again, the verbose() function isn't necessary. It just helps you troubleshoot. Good luck!

Authenticate using httr package when Making API Requests

I'm learning how to fetch data using an API in R. I understand that the aim of httr is to provide a wrapper for the curl package.
The documentation I'm following so that I make requests to the API has the following HTTP request format. This code below will be used to generate a token
curl -s \
-d "client_id=clientid” \
-d "username=user” \
-d "password=pwd” \
-d "grant_type=password" \
-d "scope=openid email" \
"https://auth.com/token"
Afterward, I'll use the token to now communicate with the API using this request
curl --header "Content-Type: application/json" \
--header "Accept: application/+json" \
--header "Authorization: Bearer token_goes_here“ \
--request GET \
--url "https://api-sitename.org/sections?parent_id=0"
Initially, I run these two requests in a terminal and they were successful, I got a response in JSON format. My question is, how do I run these requests in an R script such that I get a responses and they're it's stored in R studio global environment? My goal is to finally load the dataset from the API to the Rstudio working environment.
T
Here is something to get you started:
library(httr)
resp <- POST("https://auth.com/token",
body=list(client_id="clientid",
username="user",
password="pwd",
grant_type="password",
scope="openid email")
)
#parse for auth token here
content(resp, "text")
get_resp <- GET("https://api-sitename.org/sections?parent_id=0",
add_headers("Content-Type"="application/json",
Accept="application/+json",
"Authorization"=paste("Bearer", token))
I was able to successfully get my API call in R by replacing the content in header to body.
Here is my code
#' Th base url
base_url <- "your/url/endpoint/for/token"
# base64 encoded client id, my end-point requires to encone the client id to base64
c_id <- RCurl::base64(txt = "clinetid:sceret", mode = "character")
#' headers
headers <- httr::add_headers(
"Authorization" = paste("Basic",c_id, sep = " ")
)
# move everything else to the body. grant_type and password were requested by the endpoint
body <- list(
username = "your username",
password = "your password",
grant_type = "password",
scope = "read"
)
#' post call to get the token
httr::POST(
url = base_url,
body = body,
config = headers,
httr::accept_json()
)
When I had the user name and password in the body, I received 400 and 403 errors. Once I moved them o the body received 200 status and the token was successfully retrieved. If you can provide what you tried in R, can help you troubleshoot.

oauth2 error AADSTS90014: The request body must contain the following parameter: 'grant_type'

From the development in Windev I use Oauth 2.0 for authorization to get access to the outlook mail from a user.
The application is registered at https://apps.dev.microsoft.com without the Implicit workflow.
After the user enters the credentials, an Authorization Code is returned.
With the new code the Bearer Token is requested with a HTTP Post command.
So far, so good.
Only that the response gives an error message that makes no sense to me.
In code:
m_sHTTPUrl = "client_id=" + m_sClientID + "&client_secret=" ...
+ m_sClientSecret ...
+ "&redirect_uri=" + m_sRedirectURL + "&code=" + m_sAuthToken ...
+ "&grant_type=authorization_code"
m_sHTTPres = ""
LogLocalFile("GetAccessToken - " + m_sTokenURL + " // " + m_sHTTPUrl)
cMyRequest is httpRequest
cMyRequest..Method = httpPost
cMyRequest..URL = m_sTokenURL
cMyRequest..ContentType = "application/x-www-form-urlencoded"
cMyRequest..Header["grant_type"] = "authorization_code"
cMyRequest..Header["code"] = m_sAuthToken
cMyRequest..Header["client_id"] = m_sClientID
cMyRequest..Header["client_secret"] = m_sClientSecret
cMyRequest..Header["scope"] = m_sScope
cMyRequest..Header["redirect_uri"] = m_sRedirectURL
//cMyRequest..Content = m_sHTTPUrl
cMyResponse is httpResponse = HTTPSend(cMyRequest)
m_sHTTPres = cMyResponse.Content
In a logfile I requested the used parameters and the content of the httpResponse:
GetAccessToken - https://login.microsoftonline.com/common/oauth2/v2.0/token // grant_type=authorization_code
&code=xxxxxxx
&scope=openid+offline_access+User.Read+Email+Mail.Read+Contacts.Read
&redirect_uri=http://localhost/
&client_id=xxxxxxx
&client_secret=xxxxxxx
GetAccessToken - error = invalid_request
GetAccessToken - error_description = AADSTS90014: The request body must contain the following parameter: 'grant_type'.
The grant_type is in the header as it is supposed to be.
Does anybody have any clue of what is needed to get the OAUTH2 working ?
You shouldn't send grant_type neither in params nor in headers. Those should be sent in body params then only it will work.
Url: https://login.microsoftonline.com/common/oauth2/v2.0/token
client_id, scope and redirect_uri params can be sent as query params.
where as grant_type, code and client_secret should sent in body params.
grant_type:authorization_code,
code: {code you got from the authorization step},
client_secret: ****
You need to pass everything in body as form-data:
curl --location --request POST 'https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token' \
--form 'grant_type=authorization_code' \
--form '<the code you have got from the authorization endpoint' \
--form 'client_secret=****' \
--form 'client_id=********' \
--form 'scope=m_sScope' \
--form 'redirect_uri=http://localhost/'
you should change the content type as : application/x-www-form-urlencoded
the body must to be formated as bellow:
client_id=8cfbe8ac-8775-4c56-9302-k9d5a42cbf98
&client_secret=BOy7Q~pGvXF.SWshX72mmMnQeAkvN5elHWiYT
&grant_type=client_credentials
&resource=https://miurl.com
I finally got this right after referring to multiple answers.
POST https://login.microsoftonline.com//oauth2/token
--make sure to enter the ID directly without <,>
Use 'x-www-form-urlencoded' format for the Body.
Enter Keys & Values for the below parameters
client_id - Client_ID on your Azure App
client_secret - client_secret value and not the key. Note that this value is available only for the first time upon the client secret key creation
grant_type - client_credentials (static words, don't try to look for the value)
resource - App ID URI
reference link - https://learn.microsoft.com/en-us/previous-versions/azure/dn645543(v=azure.100)?redirectedfrom=MSDN
when providing "Default Scope" value must be full name example , "User.Read" correct value can get from azure AD APP -> Api Permission

Resources