Handle OAuth 2.0 callback: verify state, swap code for token, verify token
Source:R/methods__login.R
handle_callback.RdCheck a returning login request and exchange the provider's temporary
authorization code for an OAuthToken (OAuth 2.0 Authorization Code flow).
Use this in a custom callback handler after starting authorization with
prepare_call(). It applies shinyOAuth's state, token, and configured
identity checks while your application manages the HTTP callback and stores
the returned token. oauth_module_server() handles these responsibilities
for Shiny sessions.
Usage
handle_callback(
client,
code,
state,
browser_token,
shiny_session = NULL,
iss = NULL,
oauth_client = NULL,
payload = NULL
)Arguments
- client
An OAuthClient object.
- code
Authorization code received from the provider on a classic direct callback.
- state
Encrypted state payload returned by the provider on a classic direct callback. This should be the same value that was originally sent in
prepare_call().- browser_token
Browser token present in the user's session. This is usually managed by
oauth_module_server().- shiny_session
Optional captured Shiny session details for audit events. Normally supplied by the module; leave
NULLwhen calling directly.- iss
Optional RFC 9207 callback issuer (
iss) from the authorization response. Pass this when one callback URL can receive responses from more than one authorization server. Ifclient@enforce_callback_issuerisTRUE, this parameter is required and must match the configured provider issuer before any token exchange occurs.This low-level API cannot verify which redirect URI received the response. Clients configured with
authorization_server_mode = "multi_redirect_uri"must useoauth_module_server()instead.- oauth_client
Compatibility alias for
client. Supply only one spelling.- payload
Compatibility alias for
state. Supply only one spelling.
Value
An OAuthToken object. If callback validation, token exchange, or token verification fails, the function raises an error.
Details
Pass the returned code, the callback's state, and the
browser token saved for this login. This helper accepts direct code/state
callbacks only. For signed responses using JWT Secured Authorization
Response Mode (JARM; "jwt", "query.jwt", or
"form_post.jwt"), use oauth_module_server() and, for POST responses,
oauth_form_post_ui(). There is no public JARM resume API.
Examples
# Advanced example: your code supplies browser redirects and callback handling.
# For a Shiny app, oauth_module_server() manages these steps for you.
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"
)
# Get the login URL and store state in client's state store
# `<browser_token>` must be unpredictable and persisted for this transaction
# in storage bound to the application's exact origin (scheme, host, port).
# The module combines origin-scoped storage with an independent marker cookie
# and checks both on return. A cookie alone does not provide this boundary:
# cookies can be shared by applications on different ports of the same host.
# Shiny applications should use oauth_module_server() for the complete flow.
authorization_url <- prepare_call(client, "<browser_token>")
# Redirect user to authorization URL; retrieve code & state from the query;
# recover this transaction's `<browser_token>` through the origin-bound flow
# and verify its independent marker before calling handle_callback().
code <- "..."
state <- "..."
browser_token <- "..."
# Handle callback, exchanging code for token and validating state
token <- handle_callback(client, code, state, browser_token)
}