PaulC91 / shinyauthr

R package with shiny authentication modules
https://paulc91.github.io/shinyauthr/
Other
427 stars 81 forks source link

shinydashboard shows app without login using shinyauthr #57

Closed mrinmayik closed 2 years ago

mrinmayik commented 2 years ago

Hi Paul,

Thanks a lot for this package! I'm very new to RShiny, and have made a very simple app without reactive elements. I'm trying to add a login screen to the app using shinyauthr based on the example on the README page on Github. The login dialog box and logout button show up as expected. But for some reason, the rest of the app shows below the login dialog box even if the user is not logged in (see attached images).

Here's a short app to demonstrate the problem. Like this example, my app does not have any reactive elements that are displayed through the server function. So my server function is empty except for the lines required for shinyauthr.

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

# dataframe that holds usernames, passwords and other user data
user_base <- tibble::tibble(
  user = c("user1", "user2"),
  password = c("pass1", "pass2"),
  permissions = c("admin", "standard"),
  name = c("User One", "User Two")
)

####### Define UI for application #######
ui <- fluidPage(
  title = "Pattern Completion",
  # Application title
  titlePanel(HTML("<center>Data from New Exp</center>")),
  # add logout button UI
  div(class = "pull-right", shinyauthr::logoutUI(id = "logout")),
  # add login panel UI function
  shinyauthr::loginUI(id = "login"),
  dashboardPage(
    dashboardHeader(title=""),
    dashboardSidebar(
      sidebarMenu(
        menuItem("Pilot Experiment", tabName= "enc_pilot",startExpanded = TRUE,
                 menuSubItem("Method", tabName="enc_pilot_method", icon=icon(name="tools", lib="font-awesome")),
                 menuSubItem("Results", tabName="enc_pilot_results", icon=icon(name="chart-line", lib="font-awesome")))
      ) #sidebarMenu
    ), #dashboardSidebar
    dashboardBody(
      tabItems(
        tabItem(tabName="enc_pilot_method",
                h2(HTML("<center>METHOD</center>")),
                fluidRow(
                  box(width=12,
                      p(HTML("<strong>Objective:</strong> Some info goes here")),
                  ),
                  box(width=12,
                      h3("Study Phase"),
                      p("More info goes here."),
                  ),
                  box(width=12,
                      h3("Test Phase"),
                      p("Last box here."),
                  ) #box 
                ) #fluidRow
        ), #tabItem enc_pilot_method
        tabItem(tabName="enc_pilot_results",
                h2(HTML("<center>RESULTS</center>")),
                fluidRow(
                  box(width=12,
                      h3("Results go here"),
                  ), #box
                  box(width=12,
                      h3("More results"),
                  ), #box
                ) #fluidRow
        ) #tabItem enc_pilot_results
      ) #tabItems
    ) #dashboardBody
  ) #dashboardPage 
) #ui

####### Define server logic #######
server <- function(input, output, session) {

  # call login module supplying data frame, 
  # user and password cols and reactive trigger
  credentials <- shinyauthr::loginServer(
    id = "login",
    data = user_base,
    user_col = user,
    pwd_col = password,
    log_out = reactive(logout_init())
  )

  # call the logout module with reactive trigger to hide/show
  logout_init <- shinyauthr::logoutServer(
    id = "logout",
    active = reactive(credentials()$user_auth)
  )

  output$user_table <- renderTable({
    # use req to only render results when credentials()$user_auth is TRUE
    req(credentials()$user_auth)
    credentials()$info
  })
}

shinyApp(ui = ui, server = server)

Any suggestions on how to fix this?

Thank you, Mrinmayi

Screen Shot 2022-04-04 at 12 22 33 PM


Screen Shot 2022-04-04 at 12 24 07 PM
PaulC91 commented 2 years ago

Hi there,

So in this case you have to integrate the shinyauthr login panel shinyauthr::loginUI(id = "login") and logout button shinyauthr::logoutUI(id = "logout") inside the shinydashboard dashboardPage() UI, otherwise you will have 2 separate UI pages as you see above.

You can take a look at example code using shinyauthr with shinydashboard here and see this app in action by running shinyauthr::runExample("shinydashboard")

In your case, you will need to use sidebarMenuOutput() and uiOutput() for your sidebar and tab items in the UI and then render them in the server function only when a successful login happens with renderMenu() and renderUI().

If you run into any more issues it's best to ask for help on stackoverflow or RStudio Community (unless it's an obvious bug in the package) as you'll most likely get an answer very quickly and more people can benefit from the more visible discussion.

Good luck!