datastorm-open / shinymanager

Simple and secure authentification mechanism for single shiny applications.
https://datastorm-open.github.io/shinymanager/
386 stars 79 forks source link

Partial credential #58

Closed JasonTan-code closed 3 years ago

JasonTan-code commented 4 years ago

Hi everyone,

I am looking forward to building an app where users can use the main functions without logging in. But I also want to have a login page where users can register, so that they can store their own data. Is Shinymanager a good choice for this purpose? It seems Shinymanager requires users to log in at the very beginning, which is not what I am looking for. Any suggestions will be very appreciated.

Taotao

pvictor commented 3 years ago

Hello,

You can use the authentication module without the secure_app/secure_server logic. Here an example:

library(shiny)
library(shinymanager)

# data.frame with credentials info
credentials <- data.frame(
  user = c("user1", "user2"),
  password = c("12345", "12345"),
  stringsAsFactors = FALSE
)

# app
ui <- navbarPage(
  title = "My app",
  id = "navbar",
  tabPanel(
    title = "Main", value = "main", "Some normal content"
  ),
  tabPanel(
    title = "Secured content",
    # authentication module
    auth_ui(
      id = "auth", 
      tags_top = tags$p("You need to authenticate to continue"),
      tags_bottom = actionLink(inputId = "go_back", label = "Go back to main application")
    ),

    # result of authentication
    verbatimTextOutput(outputId = "res_auth"),

    # classic app
    headerPanel('Iris k-means clustering'),
    sidebarPanel(
      selectInput('xcol', 'X Variable', names(iris)),
      selectInput('ycol', 'Y Variable', names(iris),
                  selected=names(iris)[[2]]),
      numericInput('clusters', 'Cluster count', 3,
                   min = 1, max = 9)
    ),
    mainPanel(
      plotOutput('plot1')
    )
  )

)

server <- function(input, output, session) {

  # authentication module
  auth <- callModule(
    module = auth_server,
    id = "auth",
    check_credentials = check_credentials(credentials)
  )

  # authentication result
  output$res_auth <- renderPrint({
    reactiveValuesToList(auth)
  })

  # button to go back to app
  observeEvent(input$go_back, {
    updateNavbarPage(session, "navbar", "main")
  })

  #####################################################
  # classic app

  selectedData <- reactive({

    req(auth$result)  # <---- dependency on authentication result

    iris[, c(input$xcol, input$ycol)]
  })

  clusters <- reactive({
    kmeans(selectedData(), input$clusters)
  })

  output$plot1 <- renderPlot({
    palette(c("#E41A1C", "#377EB8", "#4DAF4A", "#984EA3",
              "#FF7F00", "#FFFF33", "#A65628", "#F781BF", "#999999"))

    par(mar = c(5.1, 4.1, 0, 1))
    plot(selectedData(),
         col = clusters()$cluster,
         pch = 20, cex = 3)
    points(clusters()$centers, pch = 4, cex = 4, lwd = 4)
  })
}

shinyApp(ui, server)

Victor

JasonTan-code commented 3 years ago

That is great! Thank you, Victor.