Introspects an access or refresh token when the provider exposes an introspection endpoint (RFC 7662). Returns a small result object describing whether introspection is supported and, when known, whether the token is active.
Authentication to the introspection endpoint mirrors the provider's
token_auth_style:
"header" (default): HTTP Basic with
client_id/client_secret."body": form fields
client_idand (when available)client_secret."public": form field
client_idonly;client_secretis never sent."client_secret_jwt" / "private_key_jwt": a signed JWT client assertion is generated (RFC 7523) and sent via
client_assertion_typeandclient_assertion, withaudresolved viaresolve_client_assertion_audience()(soclient_assertion_audienceoverrides are honored).
Usage
introspect_token(
oauth_client,
oauth_token,
which = c("access", "refresh"),
async = FALSE,
shiny_session = NULL
)Arguments
- oauth_client
OAuthClient object
- oauth_token
OAuthToken object to introspect
- which
Which token to introspect: "access" (default) or "refresh".
- async
Logical, default FALSE. If TRUE and an async backend is configured, the operation is dispatched through shinyOAuth's async promise path and this function returns a promise-compatible async result that resolves to the result list. mirai::mirai is preferred when daemons are configured via
mirai::daemons(); otherwise the current future::future plan is used. Non-sequential future plans run off the main R session;future::sequential()stays in-process.- shiny_session
Optional pre-captured Shiny session context (from
capture_shiny_session_context()) to include in audit events. Used when calling from async workers that lack access to the reactive domain.
Value
A list with fields:
supported: logical,TRUEwhen an introspection endpoint is configured.active: logical orNA, whereNAmeans the provider did not return a usable RFC 7662activevalue.raw: parsed introspection response list, orNULLwhen the endpoint is unsupported or the response could not be parsed.status: machine-readable status such as"ok","introspection_unsupported","missing_token","invalid_json","missing_active","invalid_active", or"http_<code>".
Details
Best-effort semantics:
If the provider does not expose an introspection endpoint, the function returns
supported = FALSE,active = NA, andstatus = "introspection_unsupported".If the endpoint responds with an HTTP error (e.g., 404/500) or the body cannot be parsed or does not include a usable
activefield, the function does not throw. It returnssupported = TRUE,active = NA, and a descriptivestatus(for example,"http_404","invalid_json","missing_active"). In this context,NAmeans "unknown" and will not break flows unless your code explicitly requires a definitive result (i.e.,isTRUE(result$active)).Providers vary in how they encode the RFC 7662
activefield (logical, numeric, or character variants like "true"/"false", 1/0). These are normalized to logicalTRUE/FALSEwhen possible; otherwiseactiveis set toNA.
Side effects
Performs network I/O when the provider exposes an introspection endpoint and
the selected token exists. Emits best-effort audit events and OpenTelemetry
span attributes. When async = TRUE, the work may run in a background worker.
Examples
# Please note: `get_userinfo()`, `introspect_token()`, and `refresh_token()`
# are typically not called by users of this package directly, but are called
# internally by `oauth_module_server()`. These functions are exported
# nonetheless for advanced use cases. Most users will not need to
# call these functions directly
# Example requires a real token from a completed OAuth flow
# (code is therefore not run; would error with placeholder values below)
if (interactive()) {
# Define client
client <- oauth_client(
provider = oauth_provider_github(),
client_id = Sys.getenv("GITHUB_OAUTH_CLIENT_ID"),
client_secret = Sys.getenv("GITHUB_OAUTH_CLIENT_SECRET"),
redirect_uri = "http://127.0.0.1:8100"
)
# Have a valid OAuthToken object; fake example below
# (typically provided by `oauth_module_server()` or `handle_callback()`)
token <- handle_callback(client, "<code>", "<payload>", "<browser_token>")
# Get userinfo
user_info <- get_userinfo(client, token)
# Introspect token (if supported by provider)
introspection <- introspect_token(client, token)
# Refresh token
new_token <- refresh_token(client, token, introspect = TRUE)
}