Saltar al contenido

R Shiny: autenticación de usuario para una sola aplicación.R

Luego de consultar con especialistas en la materia, programadores de diversas ramas y profesores hemos dado con la respuesta al dilema y la compartimos en esta publicación.

Solución:

ShinyProxy, un servidor Shiny de código abierto basado en Docker y Spring Java, fue diseñado para solucionar este problema. Le permite codificar usuarios en el archivo de configuración de la aplicación, conectarse a un servidor LDAP, usar SSO/Keycloak o iniciar sesión en una red social.

Aquí hay un ejemplo de cómo usar cookies para la autenticación. Más información se puede encontrar en mi blog aquí.

Primero descargue la cookie js a la carpeta www/:

if (!dir.exists('www/')) 
    dir.create('www')


download.file(
  url = 'https://cdn.jsdelivr.net/npm/[email protected]/src/js.cookie.min.js',
  destfile = 'www/js.cookies.js'
)

Instale los paquetes necesarios:

install.packages(c('shiny', 'shinyjs', 'bcrypt'))

Guarde el siguiente código como app.R y haga clic en el botón “Ejecutar aplicación”:

library(shiny)
library(shinyjs)
library(bcrypt)


# This would usually come from your user database.

# Never store passwords as clear text
password_hash <- hashpw('secret123') 

# Our not so random sessionid
# sessionid <- paste(
#   collapse = '', 
#   sample(x = c(letters, LETTERS, 0:9), size = 64, replace = TRUE)
# )
sessionid <- "OQGYIrpOvV3KnOpBSPgOhqGxz2dE5A9IpKhP6Dy2kd7xIQhLjwYzskn9mIhRAVHo" 


jsCode <- '
  shinyjs.getcookie = function(params) 
    var cookie = Cookies.get("id");
    if (typeof cookie !== "undefined") 
      Shiny.onInputChange("jscookie", cookie);
     else 
      var cookie = "";
      Shiny.onInputChange("jscookie", cookie);
    
  
  shinyjs.setcookie = function(params) 
    Cookies.set("id", escape(params),  expires: 0.5 );  
    Shiny.onInputChange("jscookie", params);
  
  shinyjs.rmcookie = function(params) 
    Cookies.remove("id");
    Shiny.onInputChange("jscookie", "");
  
'

server <- function(input, output) 

  status <- reactiveVal(value = NULL)
  # check if a cookie is present and matching our super random sessionid  
  observe(
    js$getcookie()
    if (!is.null(input$jscookie) && 
        input$jscookie == sessionid) 
          status(paste0('in with sessionid ', input$jscookie))
    
    else 
      status('out')
    
  )

  observeEvent(input$login, 
    if (input$username == 'admin' & 
        checkpw(input$password, hash = password_hash)) 
      # generate a sessionid and store it in your database,
      # sessionid <- paste(
      #   collapse = '', 
      #   sample(x = c(letters, LETTERS, 0:9), size = 64, replace = TRUE)
      # )
      # but we keep it simple in this example...
      js$setcookie(sessionid)
     else 
      status('out, cause you don't know the password secret123 for user admin.')
    
  )

  observeEvent(input$logout, 
    status('out')
    js$rmcookie()
  )

  output$output <- renderText(
    paste0('You are logged ', status())
  )


ui <- fluidPage(
  tags$head(
    tags$script(src = "js.cookies.js")
  ),
  useShinyjs(),
  extendShinyjs(text = jsCode),
  sidebarLayout(
    sidebarPanel(
      textInput('username', 'User', placeholder = 'admin'),
      passwordInput('password', 'Password', placeholder = 'secret123'),
      actionButton('login', 'Login'),
      actionButton('logout', 'Logout')
    ),
    mainPanel(
      verbatimTextOutput('output')
    )
  )
)

shinyApp(ui = ui, server = server)

Bueno, puedes hacerlo a través del código usando renderUI y cambiar la interfaz de usuario sobre la marcha. Aquí hay un ejemplo de cómo hacerlo:

library(shiny)
library(ggplot2)

u <- shinyUI(fluidPage(
  titlePanel("Shiny Password"),

  sidebarLayout(position = "left",
                sidebarPanel( h3("sidebar panel"),
                              uiOutput("in.pss"),
                              uiOutput("in.clr"),
                              uiOutput("in.titl"),
                              uiOutput("in.cnt"),
                              uiOutput("in.seed")

                ),
                mainPanel(h3("main panel"),
                          textOutput('echo'),
                          plotOutput('stdplot')
                )
  )
))

pok <- F

s <- shinyServer(function(input, output) 

  output$in.pss   <- renderUI( input$pss; if (pok) return(NULL) else return(textInput("pss","Password:","")) )
  output$in.clr   <- renderUI( input$pss; if (pok) return(selectInput("clr","Color:",c("red","blue"))) else return(NULL) )
  output$in.titl  <- renderUI( input$pss; if (pok) return(textInput("titl","Title:","Data")) else return(NULL) )
  output$in.cnt   <- renderUI( input$pss; if (pok) return(sliderInput("cnt","Count:",100,1000,500,5)) else return(NULL) )
  output$in.seed  <- renderUI( input$pss; if (pok) return(numericInput("seed","Seed:",1234,1,10000,1)) else return(NULL) )
  histdata <- reactive(
    
      input$pss;
      validate(need(input$cnt,"Need count"),need(input$seed,"Need seed"))
      set.seed(input$seed)
      df <- data.frame(x=rnorm(input$cnt))
    
  )
  observe(
     if (!pok) 
       password <- input$pss
       if (!is.null(password) && password == "pass") 
         pok <<- TRUE
       
     
   
  )
  output$echo = renderText(
    
      if (pok) 
        s <- sprintf("the %s is %s and has %d rows and uses the %d seed",
           input$ent,input$clr,nrow(histdata()),input$seed)
       else 
        s <- ""
      
      return(s)
    
  )
  output$stdplot = renderPlot(
    
      input$pss
      if (pok) 
        return(qplot(data = histdata(),x,fill = I(input$clr),binwidth = 0.2,main=input$titl))
       else 
        return(NULL)
      
    
  )

)
shinyApp(ui=u,server=s)

rendimientos

esto al iniciar sesión:

ingrese la descripción de la imagen aquí

Y esto una vez que haya ingresado la contraseña codificada "pasar".

ingrese la descripción de la imagen aquí

Por supuesto, programar de esta manera es un poco incómodo, pero podría usar pestañas y ocultarlas quizás usando una lógica similar.

O si está utilizando shinyServer, probablemente podría poner un filtro delante del sitio. Pero así es como lo abordaría en Shiny.

Si sostienes algún duda y forma de avanzar nuestro ensayo puedes dejar una apostilla y con placer lo estudiaremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *