You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shiny仪表板密码认证:内容无法绑定到对应标签页问题

解决shinydashboard结合shinyauthr时标签页内容绑定问题

我明白你遇到的问题了——你已经实现了登录认证,但标签页的内容没法正确切换,所有内容都堆在一起显示。这是因为你没有遵循shinydashboard的标准标签页结构,同时侧边栏菜单的写法也有问题。下面是修正后的完整代码,我会在后面解释关键修改点:

library(shiny)
library(shinyauthr)
library(shinyjs)
library(shinydashboard)

# 存储用户名、密码及其他用户数据的数据框
user_base <- data.frame(
  user = c("user1", "user2"),
  password = c("pass1", "pass2"),
  permissions = c("admin", "standard"),
  name = c("User One", "User Two"),
  stringsAsFactors = FALSE
)

ui <- dashboardPage(
  dashboardHeader(title = "Hello"),
  dashboardSidebar(
    # 用一个sidebarMenu包裹所有menuItem,这是shinydashboard的标准写法
    sidebarMenu(
      menuItem("Select Security", tabName = "select_security", icon = icon("lock")),
      menuItem("Portfolio", tabName = "portfolio", icon = icon("briefcase"))
    )
  ),
  dashboardBody(
    shinyjs::useShinyjs(),
    # 登录和登出控件放在顶部
    div(class = "pull-right", shinyauthr::logoutUI(id = "logout")),
    shinyauthr::loginUI(id = "login"),
    
    # 用shinydashboard的tabItems和tabItem来管理标签页内容,这是核心!
    tabItems(
      tabItem(
        tabName = "select_security",
        # 只有登录后才显示内容
        conditionalPanel(condition = "output.user_auth",
                         textOutput("welcome_note"))
      ),
      tabItem(
        tabName = "portfolio",
        conditionalPanel(condition = "output.user_auth",
                         tableOutput("user_table"))
      )
    )
  )
)

server <- function(input, output, session) {
  # 初始化登出模块
  logout_init <- callModule(shinyauthr::logout, id = "logout", active = reactive(credentials()$user_auth))
  
  # 初始化登录模块,获取认证状态
  credentials <- callModule(shinyauthr::login, id = "login",
                            data = user_base,
                            user_col = user,
                            pwd_col = password,
                            log_out = reactive(logout_init()))
  
  # 创建一个输出变量,用于conditionalPanel判断登录状态
  output$user_auth <- reactive({
    credentials()$user_auth
  })
  outputOptions(output, "user_auth", suspendWhenHidden = FALSE)
  
  # 渲染欢迎信息,只有登录后才执行
  output$welcome_note <- renderText({
    req(credentials()$user_auth)
    paste0("Hello, ", credentials()$info$name, "!")
  })
  
  # 渲染用户表格,这里用用户的权限数据做示例
  output$user_table <- renderTable({
    req(credentials()$user_auth)
    credentials()$info # 显示当前登录用户的信息
  })
}

shinyApp(ui = ui, server = server)

关键修改点说明:

  1. 修正侧边栏菜单结构:
    原来你用了多个sidebarMenu,正确的做法是用一个sidebarMenu包裹所有menuItem,每个menuItem的tabName要和后面tabItem的tabName一一对应。

  2. 使用shinydashboard标准标签页结构:
    必须用tabItems包裹各个tabItem,把对应标签页的内容放在tabItem内部,这样点击侧边栏菜单时才会正确切换显示内容,而不是所有内容都同时显示。

  3. 条件控制内容显示:
    用conditionalPanel结合output.user_auth来控制标签页内容的显示,确保未登录时看不到任何业务内容,只有登录后才会显示。同时设置outputOptions(output, "user_auth", suspendWhenHidden = FALSE)保证这个输出变量始终处于活跃状态,让条件判断生效。

  4. 优化登录后信息展示:
    利用credentials()$info可以获取当前登录用户的详细数据,比如我在欢迎信息里加入了用户名,表格直接显示用户的权限信息,让内容更贴合实际需求。

这样修改后,你就能实现登录后切换标签页显示对应内容的效果了。

内容的提问来源于stack exchange,提问作者RoboHay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:52:10