datastorm-open / shinymanager

Simple and secure authentification mechanism for single shiny applications.
https://datastorm-open.github.io/shinymanager/
379 stars 79 forks source link

shinymanager + bs4Dash + rsconnect #59

Open EAMI91 opened 3 years ago

EAMI91 commented 3 years ago

I am having some trouble figuring out what the problem should be here. Let me explain. I did an app that works perfectly in my computer and in shinyapps.io what is very strange is that returning the auth values after login are NULL when running the app in Rstudio Connect. When I replace bs4DashPage into a fluidPage or even a dashboardPage from the package shinydashboard, it works perfectly. I can't understand why using the package bs4Dash won't work only on Rstudio Connect. I would appreciate some ideas. Here is an example of my code.

library(shiny)
library(shinymanager)
library(bs4Dash)

ui <-     bs4DashPage(navbar = bs4DashNavbar(),
            sidebar = bs4DashSidebar(
              sidebarMenu(
                menuItem(text = "Crear",tabName = "uno")
              )
            ),
            body =  bs4DashBody(
              tabItems(
                tabItem(tabName = "uno",
                        verbatimTextOutput("auth_output"))
              )
            )
)

# Wrap your UI with secure_app
ui <- secure_app(ui,enable_admin = T)

server <- function(input, output, session) {

  # call the server part
  # check_credentials returns a function to authenticate users
  res_auth <- secure_server(
    check_credentials = check_credentials(db = "###.sqlite", passphrase = "###")
  )

  output$auth_output <- renderPrint({
    reactiveValuesToList(res_auth)
  })

  # your classic server logic

}

shinyApp(ui, server)
bthieurmel commented 3 years ago

Hi,

Because I can't test on RStudio Connect, it's very difficult to help you and try to find a solution... Can you have some errors in the R console and the web console ?

bthieurmel commented 3 years ago

Is the application working on Rstudio Connect using bs4Dash but removing shinymanager authentification ?

FlavioLeccese92 commented 3 years ago

Hello everyone, I'm facing the same issue and I have found a possible reason for this behaviour (not a solution unluckily).

The key-point is that the information in session$clientData$url_search is not carried over when passing from "request" in secure_app to all the observed events in secure_server. For instance;

I can confirm that simple shiny apps work correctly even when deployed on rstudio connect, as well as bs4dash is working correctly locally. I did some research and found that bs4dash refresh the URL when it does not contain a so-called WorkerId open issue here, quoting:

var workerId = $('base').attr('href');
  // ensure that this code does not locally
  if (typeof workerId != "undefined") {
    var pathname = window.location.pathname;
    var newpath = pathname + workerId;
    window.history.replaceState( {} , 'newpath', newpath);
  }

You cannot comment last line because it is needed to use the "same session". Is there an alternative way to pass token info (in a safe way) through all the parts of code? Thank you in advance for your work, I think that having it working in bs4dash+connect will give a great boost to this package!

FlavioLeccese92 commented 3 years ago

@EAMI91 I found a temporary (but satisfying) solution on this issue. This is how I solved: The problem, as I spotted, is on the shinymanager but on bs4dash side. In particular the chunk which redirects the page to an url with something like "/_w_123456" that is a workerId (necessary for apps on shinyapps.io but, as it seems to me, not on rstudio connect):

var workerId = $('base').attr('href');
  // ensure that this code does not locally
  if (typeof workerId != "undefined") {
    var pathname = window.location.pathname;
    var newpath = pathname + workerId;
    window.history.replaceState( {} , 'newpath', newpath);
  }

You can find that part of code stored into pathtoRlib\bs4Dash\bs4Dash-0.2.0\bs4Dash.js .

  1. Simply comment like this and save the file
    //window.history.replaceState( {} , 'newpath', newpath);
  2. In the App, instead of using
    library(bs4Dash)

    load it from a given personal path (where you have saved a fixed copy of the whole package and it is reachable by the connect server, maybe the working directory of the app itself):

    library("bs4Dash", lib.loc="//dir_containing_fixed_bs4dash")
  3. Deploy as usual, you will be able to have shinymanager working as it has (magnificently)

Let me know, in case you read this, if it works.

aljrico commented 3 years ago

Hi!

I am trying to deploy a Shiny App that, among other things, is capable of reading GET requests. This is possible if the user adds parameters to the address, like https://myapp.shinyapps.io/?param1=4234&param2=2342

Everything works perfectly until I moved the shinydashboard bits to bs4Dash. Whenever the user tries to input those parameters, the address gets quickly updated to https://myapp.shinyapps.io/w_88a98847/. So the request can't be captured.

Commenting out that line, as you mention, would be captured by shinyapps.io so that gets solved? Would that create other potential issues?