在R Shiny应用程序

时间:2018-04-12 19:30:19

标签: r shiny shiny-server

我有一个R Shiny应用程序,它根据当前登录的用户加载数据。特定的身份验证方法发生在上游,它在HTTP头中转发用户ID。

server.R 中,我将用户特定数据作为反应数据对象提供,基本上是这样的:

available_data <- reactivePoll(
  intervalMillis = 3600000, # one hour
  session = session,
  checkFunc = function() {
    "" # don't bother invalidating ever
  },
  valueFunc = function() {
    user_id <- fromJSON(as.list(session$request)$HTTP_SHINY_SERVER_CREDENTIALS)$user_id

    if (user_id %in% authorized_users) {
      return(get_data(user_id))
    } else {
      stop(safeError("Not authorized"))
    }
  }
)

然后我将available_data()用于数据表,图表等。这很好。

如果user_id 不是列表中的授权用户中的一个,我会获得指定的红色错误消息来代替表/图。未经授权的用户仍然可以看到所有导航,标签集,非反应内容等。我宁愿做的只是抢占所有页面呈现并将403状态代码返回给用户的浏览器。我找不到办法做到这一点。

有没有办法在Shiny应用程序中引发异常,以便根本不呈现UI?

1 个答案:

答案 0 :(得分:1)

我建议使用shinyjs启动会话,隐藏所有UI,然后仅在授权用户建立连接时显示UI。

例如,以下应用仅向登录用户显示UI。我用单选按钮替换授权状态以简化示例,但逻辑是相同的。

# ui.R

fluidPage(
  useShinyjs(),
  h1("User Authentication Example"),
  radioButtons("login", "Login:", c("Logged out", "Logged in")),
  div(id = "logged.in.ui",
    p("You are logged in")
  ) %>% shinyjs::hidden()
)

# server.R

library(shinyjs)

function(input, output) {

  # Showing/hiding UI depending on login status.
  observeEvent(input$login, {
    if (input$login == "Logged in") {
      shinyjs::show("logged.in.ui")
    } else {
      shinyjs::hide("logged.in.ui")
    }
  })

}

请注意上述应用的UI部分中的%>% shinyjs::hidden。这用于在创建会话时以及在服务器中检查登录状态之前使用JavaScript隐藏logged.in.ui div中的所有UI。在服务器中观察切换单选按钮,并根据登录状态显示或隐藏logged.in.ui div的UI内容。