Using httr in R to establish an implicit Oauth2 flow with StackOverflow.com - r

I am trying to establish an "implicit" Oauth2 authorization flow for my test connect in R to StackOverflow via the StackExchange API.
I am in situation #3 of this related post, that specifies how to set the redirect_uri and other values in a lanugage-agnostic way.
I've taken the steps described, namely setting up the app on StackApps.com to enable implicit authentication.
I've replicated the linked instructions in R with the httr library, the only major adaptation is that apparently httr requires the client secret earlier in the process than StackOverflow actually requires it.
library(httr)
# in the StackApps answer stackoverflow.com was used here.
# that just took me to the landing page.
# the docs use this URI and it gets me closer but
# it just says "Authorizing Application" with a blank page under that
# and it never completes.
end <- oauth_endpoint(authorize = "stackoverflow.com/oauth",
access = "stackoverflow.com/oauth")
client_secret = "secret_code_here"
myapp <- oauth_app("myapp",
key = "12665", # not a secret
secret = client_secret,
redirect_uri="https://stackexchange.com/oauth/login_success")
token <- oauth2.0_token(end,
myapp,
scope=NULL)
#,use_oob=T)
When I run my code a browser automatically opens and goes to StackOverflow.com. However, it just takes me to the landing page and Oauth never completes.
I tried it with use_oob=T and the only difference was that R prompted me for an authorization code that was never provided.

Related

Log in a webpage which uses github OAuth

I want to log in https://adventofcode.com/2021 programatically using httr.
I have only a very superficial understanding of the OAuth "dance", so to understand the principles I did the following:
Create an OAuth App on GitHub
Used the following code to authenticate (N.B. I know I could simply use oauth2.0_token but I felt that this workflow helped me to better understand the different messages, which are exchanged).
library(httr)
client_id <- "<my client id>"
base_url <- "https://github.com"
path <- "login/oauth/authorize"
client_secret <- "<my secret>"
url <- modify_url(base_url, path = path,
query = list(client_id = client_id,
redirect_uri = oauth_callback()))
code <- oauth_listener(url) ## needed to provide credentials in the web browser
access_token <- POST(modify_url(base_url, path = "login/oauth/access_token"),
add_headers(Accept = "application/json"),
body = list(client_id = client_id,
client_secret = client_secret,
code = code$code))
## successfully returns the values
GET("https://api.github.com/rate_limit",
add_headers(Authorization = paste(content(access_token)$access_token,
"OAUTH-TOKEN")))
From this example I think I understand the steps as highlighted in the documentation.
However, I fail to see how I could use this to login to https://adventofcode.com/2021. I have, of course, not the client_secret nor can I redirect the response to my localhost (as GitHub requires that the stored callback matches the redirect URI).
Thus, I was wondering how I could programatically login to https://adventofcode.com/2021 to fetch my task data, say?
I think you are mismatching OAuth2 roles. If you want to use adventofcode.com, you are a resource owner, adventofcode.com is a client and github is an authorization server. So you authenticate, adventofcode.com gets an auth code and then tokens. They can use the tokens to get information about your github account.
The example code you posted is different - your application is a client that gets a code and tokens from the authorization server (github) after a user was authenticated and gave a consent to passing the tokens to your app (permission delegation). So you probably cannot include adventofcode.com into this scenario.
The only way is if adventofcode.com takes a role of a resource server and their API accepts github tokens from different clients. But I know nothing about their API.

Twitter API v2.0 DELETE request using httr and R

With little experience in API programming, I am looking for a way to send a DELETE or POST request using the Twitter API v2.0 with the httr package in R. I usually use the academictwitteR package to interact with the API, but the package uses a bearer token authentication that seems to me to not be adequate for write privileges (required by DELETE and POST). Therefore, it seemed that the first step is setting up the OAuth 1.0a authentication credintials as described here. I downloaded and stored the four variables (oauth_token; oauth_token_secret; oauth_consumer_key; oauth_consumer_secret) from the app I created, but then I am stuck as to how to set up the request with httr.
I can't provide an example since I could not figure out the code, I hope you understand. Any help is much appreciated!
Not sure about your specific requirements and what you tried before.
Would it be a solution to just use the rtweet package?
It is quite handy and offers quite a lot of functions to interact with the twitter api(also posting and deleting tweets possible)
E.g.
#Posting
post_tweet("hello world")
#Following
post_follow("someuser")
# Not sure about deleting, but should work like this
post_tweet(destroy_id= "postID")
To get you post ID to delete it, you can get maybe use get_my_timeline. This should give your posts with ids.
See here in the vignette for a short intro about functions.
Of course you also need an access token first.
They have a very good explanation page on how to do this. Also a FAQ for problems. The explanation is rather long and probably too specific to go through in detail here. But would be interesting to know if it works for you.
Further things:
Make sure you have httpuv installed
Be sure to have the very latest rtweet version (best is from github I think)
Also check the following: Go to developer.twitter.com/en/apps and then to your app. Under 'Permissions' make sure to give Read and Write. Under 'App Detail' add 127.0.0.1:1410 as Callback Url. Under 'Keys and tokens' create your Keys
Regenerate your tokens/keys
So try this:
install.packages("httpuv")
devtools::install_github("mkearney/rtweet")
library(rtweet)
library(httpuv)
create_token(
app = appname,
consumer_key = key,
consumer_secret = secret,
access_token = access_token,
access_secret = access_secret
)
Update
I just saw, on the very latest version in github they completely changed their methods and create_token is now depreciated.
Here is the new way to do it: documentation
So seems you habe to use rtweet_bot() now.
library("askpass")
rtweet_bot(
api_key = askpass("API key"),
api_secret = askpass("API secret"),
access_token = askpass("access token"),
access_secret = askpass("access token")
)
The rest of the code I posted should stay the same.
In general it seems there are 3 ways of authenticating now:
rtweet_user() interactively authenticates an existing twitter user.
This form is most appropriate if you want rtweet to control your
twitter account.
rtweet_app() authenticates as a twitter application. An application
can't perform actions (i.e. it can't tweet) but otherwise has
generally higher rate limits (i.e. you can do more searches). See
details at
https://developer.twitter.com/en/docs/basics/rate-limits.html. This
form is most appropriate if you are collecting data.
rtweet_bot() authenticates as bot that takes actions on behalf of an
app. This form is most appropriate if you want to create a twitter
account that is run by a computer, rather than a human.
I looked at the curl examples for DELETE and POST requests you provided. They are rewrotten in R below. You need to replace the $OAUTH_SIGNATURE though. Please let me know if it works for you as I cannot check the code as I do not have a Twitter account nor do I have the OAuth token.
library(httr)
r <- DELETE(url = "https://api.twitter.com/2/users/2244994945/following/6253282",
add_headers('Authorization'= 'OAuth $OAUTH_SIGNATURE'))
content(r)
r <- POST(
url = "https://api.twitter.com/2/users/6253282/following",
body = c("target_user_id" = "2244994945"),
add_headers('Authorization'= 'OAuth $OAUTH_SIGNATURE'),
content_type_json()
)
content(r)

web browser authentication in GitHub Actions for Oauth token

I'm trying to use GitHub Actions to query the GitHub API using an OAuth 2.0 token through an R script. It works fine on my local machine when I run the code, where a browser window pops up indicating "Waiting for authentication in browser..." that I can manually close. When run through GitHub Actions, the workflow hangs at the "Waiting for authentication in browser..." since it's on a remote machine.
I'm using a custom R script with the httr library. The API credentials are stored as secrets for the repository I'm trying to query.
library(httr)
gh_key <- Sys.getenv('GH_KEY')
gh_secret <- Sys.getenv('GH_SECRET')
# setup app credentials
myapp <- oauth_app(appname = "data-in-r",
key = gh_key,
secret = gh_secret)
# get oauth credentials
github_token <- oauth2.0_token(oauth_endpoints('github'), app = myapp, cache = F)
# use api
gtoken <- config(token = github_token)
# get list of remote files in data folder
req <- GET("https://api.github.com/repos/tbep-tech/piney-point/contents/data", gtoken)
When the script is run through GitHub Actions, it looks like as below, where I had to manually cancel the workflow since it was hung at the browser step.
Is there a workaround for skipping the browser step so it will run on GitHub Actions? The offending repo is here.
You cannot use the 3-legged variant of OAuth2.0 (aka "web-application flow") in a headless environment like Github Actions.
If you want to use OAuth (I list other possibilities below), then you need to utilize what gitlab calls the "device-flow". See github documentation.
In this flow, there is no redirect to a given URL, so the app does not need a browser window. Instead it displays a code to the user. The user must the enter that code on a fixed URL (https://github.com/login/device). As soon as this is done, the app can request the authentication token. (So the app must keep polling until the user has entered the code).
Unfortunately, httr does not have nice wrapper functions for this variant, so you have to do the calls yourself. It can work like this:
library(httr)
app_id <- "*redacted*"
r <- POST("https://github.com/login/device/code",
body = list(
client_id = app_id,
scope = "user repo delete_repo" #Scope must be given! https://docs.github.com/en/developers/apps/building-oauth-apps/scopes-for-oauth-apps
))
device_code <- content(r)$device_code
print(paste0("Enter the code ", content(r)$user_code, " at ", content(r)$verification_uri))
## NOTE: In reality this request has to run in a loop, until the user has entered the code und the request succeeds.
## For the demo we can execute it manually after the code has been entered.
r <- POST("https://github.com/login/oauth/access_token",
body = list(
client_id = app_id,
device_code = device_code,
grant_type = "urn:ietf:params:oauth:grant-type:device_code"
))
token <- content(r)$access_token
## create and delete a private testrepository to check if everything worked
r <-
POST("https://api.github.com/user/repos",
add_headers(Authorization = paste("token", token)),
body = list(name = "testrepo",
private = TRUE,
auto_init = FALSE),
encode = "json")
r <- DELETE(paste0("https://api.github.com/repos/", content(r)$full_name),
add_headers(Authorization = paste("token", token)))
I have seen that there is httr2, and that it offers convenience functions for this flow. I have however never used it and do not know if it already works reliable. See here.
Since this flow still requires user interaction, you may be better of with one of the following variants (I do not know if they fit your use case.):
Basic Auth:
You can define what github calls a "personal access token" beforehand. With this token you can authenticate without further interaction. Creation is described here. In R you can use it most easily together with httr::authenticate.
GITHUB_TOKEN:
Github automatically creates special secrets specifically Github Actions. These can be used to execute actions in the containing repository. For more info see here.

How to fix "invalid return_url" error when creating oauth token for Trello with httr?

I want to manage my Trello cards and boards using the trelloR package but when I try to create a token with the get_token function, I get an error message on my browser : "Invalid return_url".
my_token <- get_token(key = my_key, secret = my_secret)
my_key is my personal Trello API key and my_secret is my OAuth secret. I got them on the Trello page that gives you your authentication codes, after login : https://trello.com/app-key
To use the Trello API and to access to boards, I need a token. This token is generated with OAuth1.0 by the httr package. Indeed, the function get_token do something like this, according to Jakub Chromec, author and maintainer of trelloR here :
trello.app = httr::oauth_app(
appname = "trello-app",
key = my_key,
secret = my_secret)
trello.urls = httr::oauth_endpoint(
request = "OAuthGetRequestToken",
authorize ="OAuthAuthorizeToken?scope=read&expiration=30days&name=trello-app",
access = "OAuthGetAccessToken",
base_url = "https://trello.com/1")
httr::oauth1.0_token(
endpoint = trello.urls,
app = trello.app)
When I execute this code or the function get_token with my personal key and secret, I am redirected to my browser, which is normal. As described on this page, a screen should appear asking me to allow authentication. But instead I just have an error message in the browser : "Invalid return_url".
In the RStudio console, this remains displayed :
> my_token <- get_token(my_key, my_secret)
Waiting for authentication in browser...
Press Esc/Ctrl + C to abort
I'm using httr 1.4.1, curl 4.2 and trelloR 0.6.0 with R 3.6.1 under macOS 10.15.
Some people reported the problem started after the introduction of Allowed Origins and they were able to fix it by adding the following origin:
http://localhost:1410
on the appkey page. This is a bit surprising to me as the default * should cover all origins, but there you go.
Trying this today (11/23/2019), I could not get wildcards to work as Allowed Origins. You should specify the domain of where you are running the call for authorization.
One source of confusion: The comments under "Allowed Origins" on https://trello.com/app-key refer to sites that "your application is allowed to redirect back to following the authorization flow." That was a bit confusing to me. The list should include sites you want to redirect back to IN ADDITION TO the sites you are calling Trello.authorize() from.
If you are thinking "I don't need a redirect" (and, in fact, if you are using client.js, I don't think you can specify a redirect), then those comments under "Allowed Origins" could lead you to believe you don't need to specify anything there. That would be incorrect.
Summary: Even if you want NO post-authorization re-direct, you still have to list an ORIGIN.
Also, you cannot specify file:// in Allowed Origins, so you cannot run your javascript off a local file.

How to sign R API requests with credentials

I'm trying to use Hackpad's API in R. Unlike the example in httr, the Hackpad documentation
1. uses oauth 1.0 and
2. says that the requests should be signed with your credentials.
I do not completely understand how to do the 2nd part in R (with any library). I understand how to use the request, authorize, and access URLs -- but those are not provided for Hackpad (as far as I can tell).
Here is what I tried in R (to no success):
library(httr)
myapp <- oauth_app("hackpad",
key = mykey,
secret = mysecret)
hackpad_token <- oauth1.0_token(oauth_endpoint(authorize = 'https://hackpad.com/api/1.0/',
request = 'https://hackpad.com/api/1.0/',
access = 'https://hackpad.com/api/1.0/'),
myapp)
and also
req <- GET("https://hackpad.com/api/1.0/pad/k9bpcEeOo2Q/content/latest.html",
config = authenticate(user=myuser,
password=mypass))
which tries to return the API documentation content.
Thank you for your help

Resources