I'm trying to connect to the StackExchange API in R.
When I try:
library(httr)
end <- oauth_endpoint(authorize = "https://stackoverflow.com/oauth",
access = "https://stackoverflow.com/oauth")
myapp <- oauth_app("myapp",
key = "KEY", # tried swapping these
secret = "CLIENT SECRET",
redirect_uri = "https://stackoverflow.com/oauth/login_success")
token <- oauth2.0_token(end,
myapp)
The browser opens but leads to the following message (in the browser):
Couldn't parse `client_id`
This also happens if I try it with opposite (reversed) values of key and secret, or event with key set to either value and secret=NULL (just to test without privileged access).
The StackExchange API docs say that the key value they give you is not really a secret but the client_secret value is. In the oauth_app help it says that the secret "is not equivalent to a password, and is not really a secret". Interesting.
For now I'm just trying to establish an initial test connection.
Update:
I was curious if it was actually a matter of not being able to parse special character. I tried escaping the 2 parentheses ((() in my key and client_secret. That didn't change anything. I then tried setting both to an empty string (i.e. key = "", etc) and yet that somehow led to the same result. I feel it's a clue but I still don't know what's wrong.
You're using implicit ("Client side") OAuth(SE API Doc).
That means that the auth sequence should look like this example:
Your app HTTP GETS:
https://stackexchange.com/oauth/dialog?client_id=4709&scope=private_info&redirect_uri=https://stackexchange.com/oauth/login_success
Where client_idand scope are set to your circumstances.
Your app is then redirected to:
https://stackexchange.com/oauth/login_success#access_token=wdR8Lm7m4ibD48lfrCcFxQ))&expires=86399
For example.
Where access_token is what you need for subsequent calls that require authentication.
I'm no r coder, but guess that the syntax should be something like:
myapp <- oauth_app("myapp",
client_id = "{Your App's ID}",
scope = "private_info", # Or whatever is desired. See the doc page linked above
redirect_uri = "https://stackoverflow.com/oauth/login_success")
client_secret is only used for server-side (explicit) OAuth.
pass key in all subsequent calls, OAuth needed or not, for quota purposes.
I was getting the same error, my issue was that I was using the client secret as a value for my client_id parameter
Related
At first, I am not the best programmer, so please excuse me if I ask something stupid.
I have a question about the following code (in language R) which I have written in order to get an authentication code for the Withings API:
library(httr)
my_client_id = "..." #deleted because it is secret
my_redirect_uri = "..." #deleted because it is secret
my_scope="user.activity,user.metrics,user.info"
access_url = "https://wbsapi.withings.net/v2/oauth2"
authorize_url = "https://account.withings.com/oauth2_user/authorize2"
my_response_type = "code"
my_state = "..." #deleted because it is secret
httr::BROWSE(authorize_url, query = list(response_type = my_response_type,
client_id = my_client_id,
redirect_uri = my_redirect_uri,
scope = my_scope,
state = my_state))
This code successfully opens the URL
http://%22https://account.withings.com/oauth2_user/account_login?response_type=code&client_id=...&redirect_uri=...&scope=user.activity%2Cuser.metrics%2Cuser.info&state=...&b=authorize2%22
where I can enter my e-mail-adress and password. After that, it redirects me to the URL
http://.../?code=...&state=...
where the first dots are my redirect URL. This gives me the code I need for getting the access token. I have tested the code, i.e. I tried to get an access token with using this code and I was successfull.
The problem is, I have to copy/paste the code from the URL (in my browser) to my POST statement (which I use to get the access token) manually and I would like to automatize that. So I would like to get returned the URL with the code so that I can parse it in order to extract the code. I know how to extract the code if I have the URL, but I have no idea how to avoid the copying/pasting and I am not even sure if it is possible. If it is possible, does anyone have an idea how I could add something to my existing code or how I could change my existing code in order to get the URL with the code (apart from doing it manually)?
I am very happy about any help and I want to say thank you in advance!
I am trying to access the Open Apparel Registry api using httr.
NB: It's free to sign up (need to login + get authentication code on profile page).
But you can see the swagger api docs here: https://openapparel.org/api/docs/#!/facilities/facilities_list
Here is how you authorize on web version:
oar_root_api <- "https://openapparel.org/api/facilities/"
oar_token <- XXX
oar_api_facilities_GET <- httr::GET(url = oar_root_api,
add_headers(
`Authorization` = oar_token),
verbose()
)
The code I receive back is 401 so something is wrong with my authorization, but I've tried so many ways. I can't figure out how to specify this correctly.
Sorry to hear you've been having difficulties. This additional documentation may help: https://docs.google.com/document/d/1ZKCN84Eu9WDAXUokojOw7Dcg5TAJw0vKnVk7RPrTPZ0/edit?usp=sharing
We tend to find that users need to add the "Token" prefix (see page 3), which I appreciate isn't standard practice - this is something we intend to change!
Let us know how you get on.
OAR
The Open Apparel Registry (OAR) uses Django REST Framework to provide API enpoints. The TokenAuthentication class requires that the Authorization header value have a "Token " prefix. From the documentation
For clients to authenticate, the token key should be included in the Authorization HTTP header. The key should be prefixed by the string literal "Token", with whitespace separating the two strings. For example:
Authorization: Token 9944b09.....
I am not familiar with R, but I searched for string concatenation and it looks like the paste function will build the header value that you need.
oar_root_api <- "https://openapparel.org/api/facilities/"
oar_token <- XXX
oar_api_facilities_GET <- httr::GET(url = oar_root_api,
add_headers(
`Authorization` = paste("Token ", oar_token)),
verbose()
)
I am using the "sonata-project/google-authenticator" library. It allows me to generate a QR code as follows:
$g = new \Google\Authenticator\GoogleAuthenticator();
$salt = 'XJDDJKSLJNASDJNASDASDASD';
$secret = $uid.$salt;
$url = $g->getURL($uid, 'coinula.com', $secret);
My question is around this:
The secret I provide, is that the secret that these guys are showing to the user? So that secret is the "global" key and the qr code is just a picture version of this code?
Am I supposed to store the secret and keep it safe on my side? Or is that something that the user should be able to write down and decide if he wants to keep it. I.e. Is the purpose of the secret for me NOT to store it? Or is there a reason I must store it?
Turned out to be a dumb question, but I'll answer it anyway. The secret must be stored in order for you to match it to the user. Would've been nicer if you could specify your own secret. I suppose there might be a way, but I'm going ahead with this way. So I'll be using the secret that is generated and storing that in the DB in order to compare it.
I am trying to connect Rstudio to salesforce database using 'RForcecom' package. When I type in my username, password,loginURL and apiVersion I get the following error:
Error in curl::curl_fetch_memory(url, handle = handle) :
Could not resolve host: na90.salesforce.comservices
I found the following link that explains how to go around this issue
https://akitsche.netlify.com/post/2015-07-23-r-rmarkdown/ with package called 'curl'.
As I proceed to get the proxy using ie_get_proxy_for_url command, instead of returning me the actual proxies it gives me NULL.
I am using Mac.
##Install necessary packages
install.packages("RForcecom")
library(RForcecom)
##Pick out HTTP Proxy
library('curl')
ie_get_proxy_for_url(target_url)
##Connect the exististing Salesforce account to R
connection.salesforce <- rforcecom.login(username, password loginURL, apiVersion)
I tried to use salesforcer when building a pipe into salesforce (SF). For some reason I could not get it to work (my bad) so I built the pipe from scratch.
This response is a description of how to build a data pipe into Salesforce Lightning (SF) using the SF REST API using OAuth Authorization Flow.
There are a couple of things to setup first:
You need an active SF account with username and password
You also need:
the SF token (SF emails this to you open password change)
customer key, customer secret
grant service (something like: /services/oauth2/token?grant_type=password)
login URL (something like: https://login.salesforce.com )
For the customer key & secret, grant service and login URL: consult your IT department or SF application owner.
I use package httr, to send a POST to the login URL as follows:
data <- POST(
loginurl %&% grantservice, # %&%: inline user defined function to concatenate two strings
body = list(
client_id = customerkey,
client_secret = customersecret,
username = username,
password = password %&% token
))
If all goes well, SF will respond by returning data to you and you can obtain the access token and instance URL from SF. You will need this for your subsequent GETs.
# obtain content data
content <- content(data)
access_token <- content$access_token
instance_url <- content$instance_url
id <- content$id
token_type <- content$token_type
At this time I am authorised by the SF server (for 15 minutes I believe) I am ready to run queries through GETs.
First, I have to define the request headers which contain the access token. The instance URL becomes the prefix to the query. Note that the query has to be an SOQL query in a format according to SF requirements (consult SF documentation, it is rather specific). ua is the user_agent (also an httr function).
request_headers <- c("Accept" = "application/json",
"Content-Type" = "application/json",
"Authorization" = paste0("Bearer ", access_token))
resultset <- GET(instance_url %&% query,
add_headers(request_headers), ua)
response_parsed <- content(resultset, "text", encoding="UTF-8")
SF returns data which can be extracted with the content function from httr. This will give me a JSON object which I can transform into a DF (typically DF with list columns if your query was relational).
resultset <- fromJSON(response_parsed, flatten = TRUE)
fromJSON is a function from the jsonlight package. Be prepared to do substantial post-processing on this DF to get the data in the shape you require.
SF does not like that you do things easily so here are two hurdles you need to overcome:
The length of the string sent to SF using GET is limited to around 16500 characters. This sounds like a lot but you'd be surprised how easy it is to go over this limit. For instance, my query contains an IN clause with thousands 18 character SF Identifiers. You will need to test for the length of your query and break it up into sub-queries. (I create a list of sub-queries of appropriate length and then lapply the function that GETs the records from SF).
SF returns a maximum of 2000 records for each GET. If you expect more records to be returned you need to look at 2 data elements returned from SF that will allow you to get the next set of 2000 records: nextRecordsURL and done. done is a flag that tells you if there are more records and nextRecordsURL contains the location where to send your next GET to. E.g. you can write a simple for loop that keeps going until done equals TRUE. Don't forget to combine the data you retrieve in each loop.
You will have to run multiple queries where you had expected one query to do the job. Alas.
The final hurdle to overcome is that the structure of the data from SF really depends on the query (and in extension on the database schema in SF). A query into a relational table will result in a nested list column in the DF that you get. It is really up to you to work out what is the best way to go as only you know how you structure your queries and the database schema.
A final note. I run this script on an R server on a company server inside the corporate firewall. While this is relatively safe, I made sure I did not hard code the credentials into my R code.
It is best to avoid this; people with access to the server can otherwise read your credentials. My naive approach: I created an rds file with encrypted content (using package cyphr) for all credentials. On the server, I only store the encrypted file. I created a function that reads and decrypts the rds file. I make sure that this function is only called inside the POST function call. This ensures that the credentials are only existing in RAM without encryption for the duration of the POST function call (once per session). Amateur level security stuff but better than nothing.
I'm trying to make a POST action on Bitmex to buy 1 contract called XBTUSD (bitcoin/usd) at price 4009.9, with expiring time 1545674400 (UNIX timestamp, a couple hours from now) and we need to be authenticated. This looks simple.
We are using API and we are writing in R. (api-secret is fake sorry!!!)
We need to transform our request with hmac in a signature to make it a number in base 16.
We try to define our signature
signature=hmac("Kjxd5H5sPnBq6oXmnKrQAbKPIAXuKsInHRmD9CF2Dh3-4I6j", 'POST/api/v1/order1545674400{"symbol":"XBTUSD","price":4009.0,"orderQty":1}', algo = "sha256")
and then to POST
POST("https://www.bitmex.com/api/v1/order",body = 'POST/api/v1/order1545674400{"symbol":"XBTUSD","price":4009.0,"orderQty":1}',add_headers("api-key":"R1IdBlJD0-fCXypR2TTQVCF6", "api-signature":signature))
or similar stuff, and we get
403 or 401
I don't understand what's wrong. I'm able make requests which don't need authentication, but not those with it!
Thanks!
from the first glance, you seem to have forgotten 'api-expires' parameter among headers.
Method that works for me is, that body is a named list (if you are using httr package) with aditional parameter inside 'POST' function call: encode = 'json'.
If you want to see what the errors mean in more detail, do the following:
msg = POST(....)
rawToChar(msg$content)