Skip to content

This uses oauth_flow_auth_code() to generate an access token, which is then used to authentication the request with req_auth_bearer_token(). The token is automatically cached (either in memory or on disk) to minimise the number of times the flow is performed.


  cache_disk = FALSE,
  cache_key = NULL,
  scope = NULL,
  pkce = TRUE,
  auth_params = list(),
  token_params = list(),
  host_name = "localhost",
  host_ip = "",
  port = httpuv::randomPort()



A request.


An oauth_client().


Authorization url; you'll need to discover this by reading the documentation.


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. Cached tokens are encrypted and automatically deleted 30 days after creation.


If you want to cache multiple tokens per app, use this key to disambiguate them.


Scopes to be requested from the resource owner.


Use "Proof Key for Code Exchange"? This adds an extra layer of security and should always be used if supported by the server.


List containing additional parameters passed to oauth_flow_auth_code_url()


List containing additional parameters passed to the token_url.


Host name used to generate redirect_uri


IP address web server will be bound to.


Port to bind web server to. By default, this uses a random port. You may need to set it to a fixed port if the API requires that the redirect_uri specified in the client exactly matches the redirect_uri generated by this function.


A modified HTTP request.

Security considerations

The authorization code flow is used for both web applications and native applications (which are equivalent to R packages). rfc8252 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. a public client not an confidential client) or ensure that possession of the client_secret doesn't bestow any meaningful rights.

Only modern APIs from the bigger players (Azure, Google, etc) explicitly native apps. However, in most cases, even for older APIs, possessing the client_secret gives you no ability to do anything harmful, so our general principle is that it's fine to include it in an R package, as long as it's mildly obfuscated to protect it from credential scraping. There's no incentive to steal your client credentials if it takes less time to create a new client than find your client secret.


client <- oauth_client(
  id = "28acfec0674bb3da9f38",
  secret = obfuscated(paste0(
  token_url = "",
  name = "hadley-oauth-test"

request("") %>%
  req_oauth_auth_code(client, auth_url = "")
#> <httr2_request>
#> GET
#> Body: empty
#> Policies:
#>auth_oauth: a list