如何访问反应对象?闪亮的登录示例

时间:2020-08-16 20:31:26

标签: r shiny

我在此link上找到了登录示例,但是我有一个问题:如何访问已登录的用户?我意识到此信息存储在名为auth的对象中,但是如何在不给出错误的情况下访问它?

# NOT RUN {
if (interactive()) {
  
  library(shiny)
  library(shinymanager)
  
  # data.frame with credentials info
  credentials <- data.frame(
    user = c("1","fanny", "victor"),
    password = c("1","azerty", "12345"),
    comment = c("1","alsace", "auvergne"),
    stringsAsFactors = FALSE
  )
  
  # app
  ui <- fluidPage(
    
    # authentication module
    auth_ui(
      id = "auth",
      # add image on top ?
      tags_top = 
        tags$div(
          tags$h4("Demo", style = "align:center"),
          tags$img(
            src = "https://www.r-project.org/logo/Rlogo.png", width = 100
          )
        ),
      # add information on bottom ?
      tags_bottom = tags$div(
        tags$p(
          "For any question, please  contact ",
          tags$a(
            href = "mailto:someone@example.com?Subject=Shiny%20aManager",
            target="_top", "administrator"
          )
        )
      ),
      # change auth ui background ?
      background  = "linear-gradient(rgba(0, 0, 255, 0.5),
                       rgba(255, 255, 0, 0.5)),
                       url('https://www.r-project.org/logo/Rlogo.png');"
    ),
    
    # 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)
    )
    
    output$res_auth <- renderPrint({
      reactiveValuesToList(auth) ## <---- this line print which user is logged in

    })
    
    # 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)
  
}

如何访问auth $ user?下标越界错误正在发生,我想访问在应用程序内标记为“ <------”的行上正在打印的“ auth”对象中的用户,该行将打印已登录的用户”。在我看来,如何使用反应式对象是一个错误。

我的个人情况:我正在尝试向MySQL数据库发送查询,如下所示:

  1. 尝试1(使用user_data())
user_data <- reactive({
    req(auth$result)
    auth$user
  })
connection<-reactivePoll( intervalMillis = 300,session,checkFunc = function(){
    storiesDb <- dbConnect(RMariaDB::MariaDB(), user='USER', password=localuserpassword, dbname='USER', host='localhost')
    querysel1=reactive({paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",user_data(),"' ",sep= ''
    )})
    rs = dbSendQuery(storiesDb,querysel1)
    
    dbFetch(rs) },
    valueFunc = function(){
      
      querysel1=reactive({paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",user_data(),"' ",sep= ''
                      
      )}) 
      rs = dbSendQuery(storiesDb,querysel1)
      dbFetch(rs)
    }
  )

我尝试使用user_data(),并给出错误:“无法为签名”“ MariaDBConnection”,“ reactiveExpr””'”找到函数'dbSendQuery'的继承方法

  1. 尝试2(不使用user_data())
connection<-reactivePoll( intervalMillis = 300,session,checkFunc = function(){
    storiesDb <- dbConnect(RMariaDB::MariaDB(), user='USER', password=localuserpassword, dbname='USER', host='localhost')
    querysel1=reactive({paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",auth$user,"' ",sep= ''
    )})
    rs = dbSendQuery(storiesDb,querysel1)

    dbFetch(rs) },
    valueFunc = function(){

      querysel1=reactive({paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",auth$user,"' ",sep= ''

      )}) 
      rs = dbSendQuery(storiesDb,querysel1)
      dbFetch(rs)
    }
  )

我尝试使用auth $ user,并给出错误:“ as.vector(x,“ character”)错误:无法将类型'closure'强制转换为'character'类型的vector“

  1. 尝试3(在querysel1中不响应)
connection<-reactivePoll( intervalMillis = 300,session,checkFunc = function(){
    storiesDb <- dbConnect(RMariaDB::MariaDB(), user='USER', password=localuserpassword, dbname='USER', host='localhost')
    querysel1=paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",auth$user,"' ",sep= ''
    )
    rs = dbSendQuery(storiesDb,querysel1)

    dbFetch(rs) },
    valueFunc = function(){

      querysel1=paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",auth$user,"' ",sep= ''

      ) 
      rs = dbSendQuery(storiesDb,querysel1)
      dbFetch(rs)
    }
  )

我在querysel1中尝试了无反应式,并给出了空错误:“ Error:”

在我看来,所有这些错误都是由于服务器内部的反应对象而发生的。

2 个答案:

答案 0 :(得分:1)

编辑

感谢提供reactivePoll的更多信息,我想我发现了问题:

这里的问题在于执行reactivePoll。启动应用程序时,reactivePoll已经开始执行,但是尚未登录任何用户。这意味着auth$user尚不存在(它是NULL),并且checkFunvalueFun中的代码无法处理。我提供了一个小示例(使用user = 1和password = 1)来说明它在原理上是可行的。只要auth$userNULL,我就确保不执行代码:

library(shiny)
library(shinymanager)

# data.frame with credentials info
credentials <- data.frame(
  user = c("1","fanny", "victor"),
  password = c("1","azerty", "12345"),
  comment = c("1","alsace", "auvergne"),
  stringsAsFactors = FALSE
)

# app
ui <- fluidPage(
  
  # authentication module
  auth_ui(
    id = "auth",
    # add image on top ?
    tags_top = 
      tags$div(
        tags$h4("Demo", style = "align:center"),
        tags$img(
          src = "https://www.r-project.org/logo/Rlogo.png", width = 100
        )
      ),
    # add information on bottom ?
    tags_bottom = tags$div(
      tags$p(
        "For any question, please  contact ",
        tags$a(
          href = "mailto:someone@example.com?Subject=Shiny%20aManager",
          target="_top", "administrator"
        )
      )
    ),
    # change auth ui background ?
    background  = "linear-gradient(rgba(0, 0, 255, 0.5),
                       rgba(255, 255, 0, 0.5)),
                       url('https://www.r-project.org/logo/Rlogo.png');"
  ),
  
  # 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'),
    textOutput("user_name")
  )
)

server <- function(input, output, session) {
  
  # authentication module
  auth <- callModule(
    module = auth_server,
    id = "auth",
    check_credentials = check_credentials(credentials)
  )
  
  output$res_auth <- renderPrint({
    reactiveValuesToList(auth) ## <---- this line print which user is logged in
    
  })
  
  # the following line is just an example how to use auth$user in a different
  # reactive
  user_data <- reactive({
    auth$user
  })
  
  # call the new reactive in a render function
  output$user_name <- renderText({
    paste0("The user currently logged in is: ", user_data())
  })
  
  # classic app
  selectedData <- reactivePoll(intervalMillis = 1000,
                           session,
                           checkFunc = function() {
                             if (!is.null(auth$user) && auth$user == "1") {
                               rnorm(1)
                             } else {
                               1
                             }
                           },
                           valueFunc = function() {
                             n_row <- sample(1:150, 120)
                             iris[n_row, 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)

我不确定为什么,但是仅添加req(auth$user)在这里行不通。

您可以执行以下操作:

connection<-reactivePoll( intervalMillis = 300,
                          session,
                          checkFunc = function(){
                            if (!is.null(auth$user)) {
                              storiesDb <- dbConnect(RMariaDB::MariaDB(), user='USER', password=localuserpassword, dbname='USER', host='localhost')
                              querysel1=paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",auth$user,"' ",sep= ''
                              )
                              rs = dbSendQuery(storiesDb,querysel1)
                              
                              dbFetch(rs)
                            } else {
                              NULL
                            }
                          },
                          valueFunc = function(){
                            if (!is.null(auth$user)) {
                              querysel1=paste("SELECT COL1
                 FROM   TABLENAME
                 where id ='",auth$user,"' ",sep= ''
                                              
                              ) 
                              rs = dbSendQuery(storiesDb,querysel1)
                              dbFetch(rs)
                            } else {
                              NULL
                            }
                          }
)

在这里,只要NULL不存在,我就返回auth$user,您可以根据需要进行调整。


我的旧答案:

我不确定您的问题/错误到底发生在哪里。对我来说,您的示例有效。我添加了另一个示例,说明如何访问auth$user。由于它是响应式的,因此只能在响应式上下文中访问它。

library(shiny)
library(shinymanager)

# data.frame with credentials info
credentials <- data.frame(
  user = c("1","fanny", "victor"),
  password = c("1","azerty", "12345"),
  comment = c("1","alsace", "auvergne"),
  stringsAsFactors = FALSE
)

# app
ui <- fluidPage(
  
  # authentication module
  auth_ui(
    id = "auth",
    # add image on top ?
    tags_top = 
      tags$div(
        tags$h4("Demo", style = "align:center"),
        tags$img(
          src = "https://www.r-project.org/logo/Rlogo.png", width = 100
        )
      ),
    # add information on bottom ?
    tags_bottom = tags$div(
      tags$p(
        "For any question, please  contact ",
        tags$a(
          href = "mailto:someone@example.com?Subject=Shiny%20aManager",
          target="_top", "administrator"
        )
      )
    ),
    # change auth ui background ?
    background  = "linear-gradient(rgba(0, 0, 255, 0.5),
                       rgba(255, 255, 0, 0.5)),
                       url('https://www.r-project.org/logo/Rlogo.png');"
  ),
  
  # 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'),
    textOutput("user_name")
  )
)

server <- function(input, output, session) {
  
  # authentication module
  auth <- callModule(
    module = auth_server,
    id = "auth",
    check_credentials = check_credentials(credentials)
  )
  
  output$res_auth <- renderPrint({
    reactiveValuesToList(auth) ## <---- this line print which user is logged in
    
  })
  
  # the following line is just an example how to use auth$user in a different
  # reactive
  user_data <- reactive({
    auth$user
  })
  
  # call the new reactive in a render function
  output$user_name <- renderText({
    paste0("The user currently logged in is: ", user_data())
  })
  
  # 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)

答案 1 :(得分:1)

要详细说明我的评论,也许最好显示代码:

请在注释中查看哪些语句有效,哪些无效。我只是将用户victor与通行证12345一起使用,而没有检查它是否与其他凭据一起使用。

library(shiny)
library(shinymanager)

# data.frame with credentials info
credentials <- data.frame(
  user = c("1","fanny", "victor"),
  password = c("1","azerty", "12345"),
  comment = c("1","alsace", "auvergne"),
  stringsAsFactors = FALSE
)

# app
ui <- fluidPage(
  
  # authentication module
  auth_ui(
    id = "auth",
    # add image on top ?
    tags_top = 
      tags$div(
        tags$h4("Demo", style = "align:center"),
        tags$img(
          src = "https://www.r-project.org/logo/Rlogo.png", width = 100
        )
      ),
    # add information on bottom ?
    tags_bottom = tags$div(
      tags$p(
        "For any question, please  contact ",
        tags$a(
          href = "mailto:someone@example.com?Subject=Shiny%20aManager",
          target="_top", "administrator"
        )
      )
    ),
    # change auth ui background ?
    background  = "linear-gradient(rgba(0, 0, 255, 0.5),
                       rgba(255, 255, 0, 0.5)),
                       url('https://www.r-project.org/logo/Rlogo.png');"
  ),
  
  # 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)
  )
  
  output$res_auth <- renderPrint({
    # reactiveValuesToList(auth$user) ## <---- not working
    auth[["user"]] ## <----  working
    # auth$user ## <----  this works too 
    # reactiveValuesToList(auth)[["user"]] # <--- this works too 
    
  })
  
  # 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)

}