Skip to contents

Build an httr2 request that uses the user's access token. Use this when you want to inspect or customize a request before sending it. To build and send in one step, use perform_resource_req().

Usage

resource_req(
  token,
  url,
  method = "GET",
  headers = NULL,
  query = NULL,
  follow_redirect = FALSE,
  check_url = TRUE,
  client = NULL,
  token_type = NULL,
  dpop_nonce = NULL,
  resource_hosts = NULL,
  oauth_client = NULL
)

Arguments

token

Either an OAuthToken object or a raw access token string.

url

The absolute URL to call.

method

Optional HTTP method (character). Defaults to "GET". When the effective token type is DPoP, this must be the final request method because the proof is signed against it. TRACE and the nonstandard TRACK method are rejected because authenticated requests could be reflected by the server and disclose credentials.

headers

Optional named list or named character vector of extra headers to set on the request. Header names are case-insensitive. Any user-supplied Authorization or DPoP header is ignored to ensure the token authentication set by this function is not overridden.

query

Optional named list of query parameters to append to the URL.

follow_redirect

Logical or NULL. FALSE (the default) disables HTTP redirects even when shinyOAuth.allow_redirect is enabled. NULL inherits that global option (disabled by default). Set to TRUE only if you trust all possible redirect targets and understand the security implications.

check_url

Logical. If TRUE (the default), validates url against is_ok_host() before attaching the access token. This rejects relative URLs, plain HTTP to non-loopback hosts, and when options(shinyOAuth.allowed_hosts) is set, hosts outside the allowlist. Without an allowlist this performs HTTPS and URL-syntax validation only (with the configured non-HTTPS exceptions); any HTTPS host is accepted. Set to FALSE only if you have already validated the URL and understand the security implications.

client

Optional OAuthClient. Required when the effective token type is DPoP, because the client carries the configured DPoP proof key, and also when using sender-constrained mTLS / certificate-bound tokens so shinyOAuth can attach the configured client certificate and validate any cnf thumbprint from an OAuthToken and observe any cnf thumbprint carried on a raw JWT access-token string.

token_type

Optional override for the access token type when token is supplied as a raw string. Supported values are Bearer and DPoP. Invalid or multi-valued inputs are rejected. When omitted, shinyOAuth preserves OAuthToken@token_type, and may infer DPoP from explicit OAuthToken@cnf[["jkt"]] metadata. Raw access-token strings default to Bearer unless you pass token_type = "DPoP" explicitly.

dpop_nonce

Optional DPoP nonce to embed in the proof for this request. This is primarily useful after a resource server challenges with DPoP-Nonce.

resource_hosts

Optional non-empty character vector of trusted resource host patterns, using is_ok_host() matching rules. This call-scoped allowlist adds to the global policy and is enforced even if check_url is FALSE. Use exact hostnames for URLs derived from lower-trust input. It constrains the initial URL, not redirect destinations or resolved IPs; retain follow_redirect = FALSE. NULL adds no resource-specific policy.

oauth_client

Compatibility alias for client. Supply only one spelling.

Value

An httr2 request object, ready to be performed with httr2::req_perform(). Callers may still add headers or query parameters, but when the effective token type is DPoP they must not change the request method or base URL after calling resource_req() because the proof is already bound to those values.

Details

Only send a token to an API you intend to authorize. The package applies its URL policy, timeouts, and redirect defaults. It supports Bearer authentication and tokens tied to a key (DPoP) or certificate (mTLS). For DPoP or mTLS, also supply client so the request uses the matching key or certificate.

Managed Authorization credentials cannot be combined with an access_token query parameter or form field. Inspection covers URL/query inputs and prebuilt httr2 form, raw and string bodies labelled application/x-www-form-urlencoded. JSON business fields are unaffected. File, multipart and streaming bodies are not parsed; callers must ensure these contain no additional OAuth credential transport. Later request changes outside these helpers require a new check.

DPoP note

DPoP proofs bind the current HTTP method and target URI (without query or fragment). Use the query argument to preserve encoded resource paths; external URL modifiers can decode reserved path characters. Changing the method, scheme, host, or path invalidates the proof.

Examples

# Make request using OAuthToken object
# (code is not run because it requires a real token from user interaction)
if (interactive()) {
  # Inside reactive server code, after login has succeeded:
  token <- auth[["token"]]

  # Recommended for most callers: build + perform in one step.
  response <- perform_resource_req(
    token,
    "https://api.example.com/resource",
    query = list(limit = 5)
  )

  # Build only when you need to inspect the request yourself.
  request <- resource_req(
    token,
    "https://api.example.com/resource",
    query = list(limit = 5)
  )

  # Inspect request settings without printing authentication headers.
  # httr2::req_perform(request) sends it when ready.

  # Or start from your own httr2 request and still let shinyOAuth perform it
  # so DPoP nonce retries remain available.
  custom_request <- httr2::request("https://api.example.com/resource") |>
    httr2::req_headers(Accept = "application/json") |>
    httr2::req_url_query(limit = 5)

  response <- perform_resource_req(token, custom_request)

  # Constrain dynamic URLs before attaching a token. check_url alone does not
  # restrict HTTPS hosts unless a global allowed_hosts policy is configured.
  response <- perform_resource_req(
    token,
    input[["resource_url"]],
    resource_hosts = "api.example.com",
    follow_redirect = FALSE
  )
}