Rhino puts strong emphasis on modularization and for consistency even the outermost UI and server are defined as a Shiny module. Unfortunately, shinymanager::secure_app() cannot be placed in a Shiny module as it is designed to be passed directly to shiny::shinyApp().

To overcome this you can setup a legacy entrypoint in your rhino.yml. Please be aware that it is a workaround and not a setting recommended for all cases:

legacy_entrypoint: box_top_level

After adding shinymanager to your dependencies you can use it in app/main.R as follows:

box::use(
  shiny,
  shinymanager,
)

# Define your `check_credentials` function.
# This is just an example. Do not hard-code the credentials in your actual application.
check_credentials <- shinymanager$check_credentials(
  data.frame(user = "admin", password = "admin")
)

#' @export
ui <- shinymanager$secure_app( # Wrap your entire UI in `secure_app()`.
  shiny$bootstrapPage(
    shiny$textInput("name", "Name"),
    shiny$textOutput("message")
  )
)

#' @export
server <- function(input, output) {
  # Call `secure_server()` at the beginning of your server function.
  shinymanager$secure_server(check_credentials)
  output$message <- shiny::renderText(paste0("Hello ", input$name, "!"))
}

This is just an example. Do not hard-code the credentials in your actual application. Store them in a database or use environment variables.

Bookmarking

If you want to use bookmarking together with shinymanager, you will need to wrap the UI passed to secure_app() in a function:

shiny$enableBookmarking()

#' @export
ui <- shinymanager$secure_app(
  # Wrap the UI passed to `secure_app()` in a function with a `request` parameter.
  function(request) {
    shiny$bootstrapPage(
      shiny$bookmarkButton(),
      shiny$textInput("name", "Name"),
      shiny$textOutput("message")
    )
  }
)


Appsilon/rhino documentation built on Sept. 27, 2024, 7:01 p.m.