Authenticate using the OAuth authorization code flow, as defined by Section 4.1 of RFC 6749.
This flow is the most commonly used OAuth flow where the user
opens a page in their browser, approves the access, and then returns to R.
When possible, it redirects the browser back to a temporary local webserver
to capture the authorization code. When this is not possible (e.g., when
running on a hosted platform like RStudio Server), provide a custom
redirect_uri
and httr2 will prompt the user to enter the code manually.
Learn more about the overall OAuth authentication flow in https://httr2.r-lib.org/articles/oauth.html, and more about the motivations behind this flow in https://stack-auth.com/blog/oauth-from-first-principles.
Usage
req_oauth_auth_code(
req,
client,
auth_url,
scope = NULL,
pkce = TRUE,
auth_params = list(),
token_params = list(),
redirect_uri = oauth_redirect_uri(),
cache_disk = FALSE,
cache_key = NULL,
host_name = deprecated(),
host_ip = deprecated(),
port = deprecated()
)
oauth_flow_auth_code(
client,
auth_url,
scope = NULL,
pkce = TRUE,
auth_params = list(),
token_params = list(),
redirect_uri = oauth_redirect_uri(),
host_name = deprecated(),
host_ip = deprecated(),
port = deprecated()
)
Arguments
- req
A httr2 request object.
- client
An
oauth_client()
.- auth_url
Authorization url; you'll need to discover this by reading the documentation.
- scope
Scopes to be requested from the resource owner.
- pkce
Use "Proof Key for Code Exchange"? This adds an extra layer of security and should always be used if supported by the server.
- auth_params
A list containing additional parameters passed to
oauth_flow_auth_code_url()
.- token_params
List containing additional parameters passed to the
token_url
.- redirect_uri
URL to redirect back to after authorization is complete. Often this must be registered with the API in advance.
httr2 supports three forms of redirect. Firstly, you can use a
localhost
url (the default), where httr2 will set up a temporary webserver to listen for the OAuth redirect. In this case, httr2 will automatically append a random port. If you need to set it to a fixed port because the API requires it, then specify it with (e.g.)"http://localhost:1011"
. This technique works well when you are working on your own computer.Secondly, you can provide a URL to a website that uses Javascript to give the user a code to copy and paste back into the R session (see https://www.tidyverse.org/google-callback/ and https://github.com/r-lib/gargle/blob/main/inst/pseudo-oob/google-callback/index.html for examples). This is less convenient (because it requires more user interaction) but also works in hosted environments like RStudio Server.
Finally, hosted platforms might set the
HTTR2_OAUTH_REDIRECT_URL
andHTTR2_OAUTH_CODE_SOURCE_URL
environment variables. In this case, httr2 will useHTTR2_OAUTH_REDIRECT_URL
for redirects by default, and poll theHTTR2_OAUTH_CODE_SOURCE_URL
endpoint with the state parameter until it receives a code in the response (or encounters an error). This delegates completion of the authorization flow to the hosted platform.- cache_disk
Should the access token be cached on disk? This reduces the number of times that you need to re-authenticate at the cost of storing access credentials on disk.
Learn more in https://httr2.r-lib.org/articles/oauth.html.
- cache_key
If you want to cache multiple tokens per app, use this key to disambiguate them.
- host_name, host_ip, port
Value
req_oauth_auth_code()
returns a modified HTTP request that will
use OAuth; oauth_flow_auth_code()
returns an oauth_token.
Security considerations
The authorization code flow is used for both web applications and native
applications (which are equivalent to R packages). RFC 8252 spells out
important considerations for native apps. Most importantly there's no way
for native apps to keep secrets from their users. This means that the
server should either not require a client_secret
(i.e. it should be a
public client and not a confidential client) or ensure that possession of
the client_secret
doesn't grant any significant privileges.
Only modern APIs from major providers (like Azure and Google) explicitly
support native apps. However, in most cases, even for older APIs, possessing
the client_secret
provides limited ability to perform harmful actions.
Therefore, our general principle is that it's acceptable to include it in an
R package, as long as it's mildly obfuscated to protect against credential
scraping attacks (which aim to acquire large numbers of client secrets by
scanning public sites like GitHub). The goal is to ensure that obtaining your
client credentials is more work than just creating a new client.
See also
oauth_flow_auth_code_url()
for the components necessary to
write your own auth code flow, if the API you are wrapping does not adhere
closely to the standard.
Other OAuth flows:
req_oauth_bearer_jwt()
,
req_oauth_client_credentials()
,
req_oauth_password()
,
req_oauth_refresh()
,
req_oauth_token_exchange()
Examples
req_auth_github <- function(req) {
req_oauth_auth_code(
req,
client = example_github_client(),
auth_url = "https://github.com/login/oauth/authorize"
)
}
request("https://api.github.com/user") |>
req_auth_github()
#> <httr2_request>
#> GET https://api.github.com/user
#> Body: empty
#> Policies:
#> • auth_sign: a list
#> • auth_oauth: TRUE