shinyOAuth

R-CMD-check Integration tests (Keycloak) CRAN status

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.

Features

Installation

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")

Usage

See vignette("usage", package = "shinyOAuth") (online guide) for login buttons, authenticated API calls, configuration and deployment settings.

Minimal example

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.

Logging/auditing

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).

More information

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").

For developers: tests & integration tests

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.