shinyOAuth is an R package for OpenID Connect (OIDC) authentication and OAuth 2.0 authorization in Shiny apps. Users can sign in with existing accounts and give your app permission to call APIs on their behalf.
The package works across OAuth 2.0 and OIDC providers, including services such as Google, Microsoft, Auth0 and Okta, and self-hosted providers such as Keycloak. You can use built-in provider helpers, discover OIDC settings automatically, or connect to other providers by configuring their endpoints and authentication settings yourself.
The Shiny module manages the sign-in process, from redirects and callbacks to OIDC token validation, user information and token refresh. Your Shiny app can use authentication status, tokens and user information as reactive values. You can also reuse the user’s sign-in with other R packages and database drivers that accept OAuth access tokens. shinyOAuth supplies a current token, refreshing it when needed.
Shiny module: oauth_module_server() manages login,
callbacks and token refresh. It returns reactive values for login
status, tokens and user information.
S7 classes: OAuthProvider, OAuthClient
and OAuthToken describe the provider, your app’s
registration and the tokens it receives.
Functions for custom integrations: use
prepare_call(), handle_callback(),
introspect_token() and refresh_token() to
manage the flow yourself.
Provider setup: use built-in helpers for GitHub, Google,
Microsoft, Keycloak and Auth0, discover OIDC settings with
oauth_provider_oidc_discover(), or configure a provider
yourself.
Security: AES-GCM-encrypted state, single-use server-side state,
origin- and tab-scoped browser binding, HTTPS enforcement and PKCE
(S256). OIDC checks cover ID token signatures and claims, including
nonce, and match the UserInfo subject to the ID token. DPoP, mTLS, JAR
and PAR are available for providers that require them. See
vignette("authentication-flow", package = "shinyOAuth") (online
guide).
Asynchronous execution: provider requests can run in background workers to keep other Shiny sessions responsive. See the setup instructions.
Diagnostics: record login successes, failures and other events
with audit hooks or OpenTelemetry. See
vignette("audit-logging", package = "shinyOAuth") (online
guide) and
vignette("opentelemetry", package = "shinyOAuth") (online
guide).
Install from CRAN:
install.packages("shinyOAuth")Install the development version from GitHub:
if (!requireNamespace("remotes", quietly = TRUE)) {
install.packages("remotes")
}
remotes::install_github("lukakoning/shinyOAuth")See vignette("usage", package = "shinyOAuth") (online
guide) for login buttons, authenticated API calls, configuration and
deployment settings.
Register a GitHub OAuth app in your GitHub Developer
Settings, using http://127.0.0.1:8100 as the callback
URL. Set GITHUB_OAUTH_CLIENT_ID and
GITHUB_OAUTH_CLIENT_SECRET in your R environment before
running the example. The environment
setup instructions show how to store these values in
.Renviron.
library(shiny)
library(shinyOAuth)
provider <- oauth_provider_github()
# App registration
client <- oauth_client(
provider = provider,
client_id = Sys.getenv("GITHUB_OAUTH_CLIENT_ID"),
client_secret = Sys.getenv("GITHUB_OAUTH_CLIENT_SECRET"),
redirect_uri = "http://127.0.0.1:8100",
scopes = c("read:user", "user:email")
)
# Simple UI
ui <- oauth_ui(fluidPage(
# Show login information:
uiOutput("login_information")
), id = "auth", client = client)
# Server which obtains authentication
server <- function(input, output, session) {
# Login and callback handling, with reactive status and token data
auth <- oauth_module_server("auth", client)
# Render login information:
output[["login_information"]] <- renderUI({
if (auth[["authenticated"]]) {
user_info <- auth[["token"]]@userinfo
tagList(
tags[["p"]]("You are logged in! Your details:"),
tags[["pre"]](paste(capture.output(str(user_info)), collapse = "\n"))
)
} else {
tags[["p"]]("You are not logged in.")
}
})
}
runApp(
shinyApp(ui, server), port = 8100,
launch.browser = FALSE
)
# Open the app in your regular browser at http://127.0.0.1:8100
# (viewers in RStudio/Positron/etc. cannot perform necessary redirects)On Posit Connect and Connect Cloud, the direct app URL supports the browser navigation used during login; embedded dashboard previews can block redirects. See deployment settings.
Use audit hooks to record callbacks and login outcomes, or send logs and traces to a monitoring service through OpenTelemetry.
For R hook examples, see
vignette("audit-logging", package = "shinyOAuth") (online
guide). For exporter setup, see
vignette("opentelemetry", package = "shinyOAuth") (online
guide).
Authentication
flow explains how the package handles login requests, callbacks and
token checks. The deployment
guide covers hosted app configuration. You can also read these
guides in R with
vignette("authentication-flow", package = "shinyOAuth") and
vignette("usage", package = "shinyOAuth").
The ‘testthat’ tests are in tests/testthat/. Integration
tests in integration/keycloak/ use a local Keycloak
instance in Docker or Podman and include browser tests with ‘shinytest2’
and ‘chromote’. Demo deployments are in integration/gcp/
for Google Cloud Run and integration/posit/ for Posit
Connect Cloud.